'Move field matching pattern to first field
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.
Solution 1:[1]
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
Solution 2:[2]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | RARE Kpop Manifesto |
