Print second-to-last column/field in `awk`

Awk

Awk 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 }'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBrian GView Question on Stackoverflow
Solution 1 - AwkChris KannonView Answer on Stackoverflow
Solution 2 - AwkprogzView Answer on Stackoverflow
Solution 3 - AwkSteveView Answer on Stackoverflow
Solution 4 - Awkghostdog74View Answer on Stackoverflow
Solution 5 - AwkfedorquiView Answer on Stackoverflow
Solution 6 - AwkVIPIN KUMARView Answer on Stackoverflow
Solution 7 - AwkChris KoknatView Answer on Stackoverflow
Solution 8 - AwkFdvView Answer on Stackoverflow
Solution 9 - Awksan1512View Answer on Stackoverflow