Print second-to-last column/field in `awk`
AwkAwk Problem Overview
I want to print the second-to-last column or field in awk
. The number of fields is the NF
variable. I know that I should be able to use $NF
, but I'm not sure how it can be used.
And this does not seem to work:
awk ' { print ( $NF-- ) } '
Awk Solutions
Solution 1 - Awk
awk '{print $(NF-1)}'
Should work
Solution 2 - Awk
Small addition to Chris Kannon' accepted answer: only print if there actually is a second last column.
(
echo | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2 | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2 3 | awk 'NF && NF-1 { print ( $(NF-1) ) }'
)
Solution 3 - Awk
It's simplest:
awk '{print $--NF}'
The reason the original $NF--
didn't work is because the expression is evaluated before the decrement, whereas my prefix decrement is performed before evaluation.
Solution 4 - Awk
awk ' { print ( $(NF-1) ) }' file
Solution 5 - Awk
You weren't far from the result! This does it:
awk '{NF--; print $NF}' file
This decrements the number of fields in one, so that $NF
contains the former penultimate.
Test
Let's generate some numbers and print them on groups of 5:
$ seq 12 | xargs -n5
1 2 3 4 5
6 7 8 9 10
11 12
Let's print the penultimate on each line:
$ seq 12 | xargs -n5 | awk '{NF--; print $NF}'
4
9
11
Solution 6 - Awk
First decrements the value and then print it -
awk ' { print $(--NF)}' file
OR
rev file|cut -d ' ' -f2|rev
Solution 7 - Awk
Perl solution similar to Chris Kannon's awk solution:
perl -lane 'print $F[$#F-1]' file
These command-line options are used:
-
n
loop around every line of the input file, do not automatically print every line -
l
removes newlines before processing, and adds them back in afterwards -
a
autosplit mode – split input lines into the@F
array. Defaults to splitting on whitespace -
e
execute the perl code
The @F
autosplit array starts at index [0] while awk fields start with $1.
$#F
is the number of elements in @F
Solution 8 - Awk
Did you tried to start from right to left by using the rev command ? In this case you just need to print the 2nd column:
seq 12 | xargs -n5 | rev | awk '{ print $2}' | rev
4
9
11
Solution 9 - Awk
If you have many columns and want to print all but not the three cloumns in the last, then this might help
awk '{ $NF="";$(NF-1)="";$(NF-2)="" ; print $0 }'