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