awk: fields and printing

grep, sed & awk · Essentials · 12 min

Pulling columns out of logs, ps output or CSV-ish files is awk's bread and butter.

An awk program is a list of pattern { action } rules run on every input line (a record). Each record is split into fields: $1, $2, ... and $0 is the whole line. By default fields are separated by runs of spaces and tabs, and leading blanks are ignored, which suits command output like ps or ls -l.

Built-in variables you'll use straight away:

  • NF number of fields on this line, so $NF is the last field and $(NF-1) the one before.
  • NR the current record number (line number across all input).
  • -F ',' (or -F':') sets the field separator FS; it can be a single character or a regex such as -F '[,;]'.

print a, b prints its arguments separated by the output field separator OFS (a space by default) followed by a newline. print a b (no comma) concatenates them. To change OFS use -v OFS='\t' or set it in a BEGIN block.

Always put the program in single quotes so the shell doesn't expand $1 itself.

Note that -F ',' is not a CSV parser: a quoted field containing a comma will be split. For real CSV use a CSV-aware tool, or gawk's --csv option (gawk 5.3+).

Example

printf 'alice 31 london\nbob 25 paris\ncarol 40 rome\n' > people.txt

awk '{ print $1 }' people.txt             # alice / bob / carol
awk '{ print $3, $1 }' people.txt         # london alice ...
awk '{ print NR ": " $1 " is " $2 }' people.txt
# 1: alice is 31 ...
awk '{ print $NF }' people.txt            # last field: london / paris / rome

# /etc/passwd style: user name and shell
printf 'root:x:0:0:root:/root:/bin/bash\n' | awk -F: '{ print $1, $NF }'
# root /bin/bash

awk -v OFS='\t' '{ print $1, $2 }' people.txt    # tab-separated output

Remember

  • $1..$NF are fields, $0 the whole line, NR the line number
  • -F sets the input separator; OFS controls what print puts between values
  • Single-quote the program so the shell leaves $1 alone

Watch out for

  • Using double quotes around the program: the shell replaces $1 with its own (usually empty) argument.

Check yourself

  1. For the line 'a b c d', what does awk '{ print $(NF-1) }' print?
  2. What does awk '{ print $1 $2 }' print for the line 'x y'?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.gnu.org/software/gawk/manual/gawk.html#Fields