Home > Mobile >  Move field matching pattern to first field
Move field matching pattern to first field

Time:04-11

I have a file of hundreds of lines e.g:

CAT FROG DOG PIG

DOG PIG BIRD HORSE

HORSE FROG PIG

And I wand to move any field containing "PIG" to the first field as below:

PIG CAT FROG DOG

PIG DOG BIRD HORSE

PIG HORSE FROG

Is it possible to do in an awk one liner? I was trying to reverse engineer this line I found in another thread that moves fields matching a pattern to the end but my knowledge of awk is not great:

awk '{ for(i=1; i<=NF; i ) if($i~/PIG/) a[i] ; } {for(i in a){str=str $i FS; $i=""} $0=$0 FS str; $1=$1; str=""}1' file

Many thanks for any help.

CodePudding user response:

awk '{
    out = $1
    for (i=2; i<=NF; i  ) {
        out = ($i ~ /PIG/ ? $i OFS out : out OFS $i)
    }
    print out
}'

Original answer below would produce the posted expected output from the posted sample input but would fail in some of the non-trivial cases not covered by the provided sample input as the assignment to $0 in the loop resplits the record, renumbering the fields and so could skip a field:

awk '{
    for (i=1; i<=NF; i  ) {
        if ($i ~ /PIG/) {
            tmp = $i
            $i = ""
            $0 = tmp FS $0
        }
    }
    $1 = $1
    print
}' file

CodePudding user response:

Here's a one-liner solution:

echo
echo "${test1}"
echo

<<<"${test1}" mawk '(NF*=!_<NF) && \
                          sub("^",FS" ") \
                      gsub("[ \t] "," ")' FS='PIG' OFS=''

CAT FROG DOG PIG
DOG PIG BIRD HORSE
HORSE FROG PIG
FROG DOG HORSE

PIG CAT FROG DOG 
PIG DOG BIRD HORSE
PIG HORSE FROG 
  • Related