TIL: Reorder columns, print the last with awk

awk is a whole programming language, but 90% of what I use it for is printing a subset of columns. This is pretty much covered by cut with two exceptions: re-ordering columns and printing the last column. Both cut and awk call columns “fields”.

Here’s some sample tab-separated data (formatted with column -t!):

FirstName  LastName  FavoriteColor  Pet
Elena      Kowalski  yellow         hamster
Marcus     Rivera    green          snake
Nadia      Ferreira  coral          rabbit
Yuki       Tanaka    pink           cat
Zara       Okonkwo   indigo         chinchilla

If you just want a list of favorite colors, you select the third field with cut -f3:

cat data.tsv | cut -f3
FavoriteColor
yellow
green
coral
pink
indigo

But if you want last name then first name, no dice. You can run cut -f2,1 but it will output them in the original order. For this I learned to use awk. You have to remember to specify the field separator with -F, then you put the program to run on each line in braces:

cat data.tsv | awk -F'\t' '{ print $2, $1 }'
LastName FirstName
Kowalski Elena
Rivera Marcus
Ferreira Nadia
Tanaka Yuki
Okonkwo Zara

If you want the last field in the input (in my case I was looking at log lines), you have two options: count the number of fields and use cut (no thanks, I’m too lazy) or use awk. The variable you want is $NF for “number of fields”. Since the fields are one-indexed, this will give you the last field.

cat data.tsv | awk -F'\t' '{ print $NF }'
Pet
hamster
snake
rabbit
cat
chinchilla

I usually have to look up -F'\t' even though I should probably remember “field separator” is -F.