tags:

views:

304

answers:

4

If text lines of indeterminate width had in a file had text "Line-to-reorder", and I only wanted to flip and display the order of the first three tokens I can do:

# cat file.txt | awk '/Line-to-reorder/ { print $3 $2 $1 }'

How can I let lines of text that don't have the matching criteria pass through unaltered?

Secondly, How can I display the remainder of the tokens (the remainder of the line) on the matched line?

(awk is the tool of choice since my embedded system's busybox implementation has it.)

+1  A: 

This reference may help

Dave
Thanks. It did.
Jamie
+1  A: 

best option is probably to match all lines (no pattern) and then do if ... else in the action.

something like { if ($0 ~ /Line-to-reorder/) print $3 $2 $1 else print $0 }

Kevin Peterson
Even better. although I had to do: if ($0 ~ /Line-to-reorder/) { print $3 $2 $1} else { print $0 } }
Jamie
+1  A: 

It's not necessary to do any if...else, just do a match/not-match.

This prints fields 3, 2, and 1 followed by the rest of the fields in their original order if the line matches. If it doesn't, it prints the whole line as-is.

awk '/Line-to-reorder/ {printf "%s %s %s", $3, $2, $1; for (i=4; i<=NF; i++) {printf " %s", $i }; printf "\n"} !/Line-to-reorder/ {print}' file.txt

Broken out into an awk script:

#!/usr/bin/awk -f
/Line-to-reorder/ {
        printf "%s %s %s", $3, $2, $1
        for (i=4; i<=NF; i++) {
                printf " %s", $i
        }
        printf "\n"
}
!/Line-to-reorder/ {print}

Run this with something like:

awkscript file.txt

This awk script takes a filename as an argument (because awk does) and so cat isn't necessary for either invocation method.

Dennis Williamson
+1 - I've come back to this as a useful reference. Thanks.
Jamie
+2  A: 

This simple script answers both your questions:

awk '/Line-to-reorder/ {tmp = $1; $1 = $3; $3 = tmp} {print}' file.txt
  • you can assign to fields to edit the line
  • no need for cat
  • prints (all the fields of) every line
glenn jackman
Best yet. Thanks.
Jamie
can golf it a bit: `awk '/Line-to-reorder/ {tmp = $1; $1 = $3; $3 = tmp} 1' file.txt`
glenn jackman