awk Cheat Sheet

Most used
awk '{print $1}' file                  # first column (whitespace-separated)
awk -F: '{print $1, $7}' /etc/passwd   # custom separator
awk '$3 > 100' file                    # rows where column 3 > 100
awk '/error/ {print $NF}' file         # last field of matching lines
awk '{s += $2} END {print s}' file     # sum a column
awk 'NR==5, NR==10' file               # lines 5 to 10

An awk program is a list of pattern { action } rules run against every input line. If the pattern is missing, the action runs on every line; if the action is missing, the line is printed. awk splits each line into fields $1, $2… on whitespace by default. Always wrap the program in single quotes so the shell does not expand $1.

Which awk you have depends on the distro: Fedora, Arch and openSUSE ship gawk; Debian, Ubuntu and Mint ship mawk unless you install gawk (sudo apt install gawk). Everything in the first sections works in both; gawk-only features are marked.

Printing fields

CommandWhat it does
awk '{print}' fPrint every line (same as cat)
awk '{print $1, $3}' fPrint columns 1 and 3, separated by a space (OFS)
awk '{print $1 $3}' fPrint them joined with no separator
awk '{print $NF}' fLast field
awk '{print $(NF-1)}' fSecond-to-last field
awk '{print NR": "$0}' fPrefix each line with its line number
awk '{print NF}' fNumber of fields on each line
awk '{$2=""; print}' fDrop column 2 (leaves an extra separator)
awk '{printf "%-20s %8.2f\n", $1, $2}' fFormatted output with C-style printf
awk '{print length($0)}' fLength of each line

Separators

CommandWhat it does
awk -F: '...' fInput field separator is :
awk -F',' '...' fComma-separated (simple CSV without quoted commas)
awk -F'\t' '...' fTab-separated
awk -F'[:,]' '...' fRegex separator: colon or comma
awk -v OFS=',' '{$1=$1; print}' fConvert whitespace to commas ($1=$1 forces the line to be rebuilt with OFS)
awk 'BEGIN {FS=":"; OFS="\t"} {print $1,$3}' fSet separators in a BEGIN block
awk -v RS='' '{print $1}' fParagraph mode: blank lines separate records
gawk --csv '{print $2}' f.csvgawk 5.3+: real CSV parsing, handles quoted fields

Patterns and conditions

CommandWhat it does
awk '/regex/' fLines matching a regex (like grep)
awk '!/regex/' fLines not matching
awk '$1 == "root"' fExact field comparison
awk '$5 ~ /^ERR/' fField matches a regex
awk '$5 !~ /^ERR/' fField does not match
awk '$3 >= 50 && $3 < 100' fNumeric range with logical AND (|| for OR)
awk 'NR > 1' fSkip the header line
awk 'NF' fSkip empty lines (NF is 0, which is false)
awk '/start/,/end/' fRange from a matching line to the next matching line
awk 'length > 80' fLines longer than 80 characters
awk '{if ($3 > 0) print "pos"; else print "neg"}' fif/else inside an action

Built-in variables

CommandWhat it does
$0The whole current record (line)
$1 ... $NFFields of the current record
NRRecord number across all input
FNRRecord number within the current file
NFNumber of fields in the current record
FS / OFSInput / output field separator
RS / ORSInput / output record separator (default newline)
FILENAMEName of the current input file
ENVIRON["HOME"]Environment variables
awk -v lim="$LIMIT" '$2 > lim' fPass a shell variable into awk safely

Arithmetic, arrays and functions

CommandWhat it does
awk '{s+=$1} END {print s}' fSum a column
awk '{s+=$1} END {print s/NR}' fAverage
awk 'max=="" || $1>max {max=$1} END {print max}' fMaximum value
awk '{c[$1]++} END {for (k in c) print c[k], k}' fCount occurrences of each value (array)
awk '{s[$1]+=$2} END {for (k in s) print k, s[k]}' fSum column 2 grouped by column 1
awk '!seen[$0]++' fRemove duplicate lines, keeping order
awk '{print toupper($1)}' ftoupper, tolower
awk '{print substr($1, 1, 3)}' fSubstring: start position (1-based), length
awk '{gsub(/foo/, "bar"); print}' fReplace all matches in the line (sub replaces the first)
awk '{n=split($0, a, ","); print a[n]}' fSplit a string into an array
awk 'match($0, /[0-9]+/) {print substr($0, RSTART, RLENGTH)}' fExtract the first number on each line
gawk '{print strftime("%F %T", $1)}' fgawk only: format a Unix timestamp
gawk -i inplace '{gsub(/a/,"b")} 1' fgawk only: edit a file in place

Common recipes

Disk usage above 80% from df:

df -h | awk 'NR>1 && $5+0 > 80 {print $6, $5}'

Top 10 client IPs in an nginx or Apache access log:

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
# or entirely in awk:
awk '{c[$1]++} END {for (ip in c) print c[ip], ip}' access.log | sort -rn | head

Count HTTP status codes (field 9 in the combined log format):

awk '{print $9}' access.log | sort | uniq -c | sort -rn

List human users (UID 1000 and up) with their shells:

awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $7}' /etc/passwd

Total memory used by a process name, from ps (RSS in KiB):

ps -eo rss,comm | awk '$2=="firefox" {s+=$1} END {printf "%.1f MiB\n", s/1024}'

Print lines where a column changed compared to the previous line:

awk '$1 != prev {print; prev = $1}' sorted.txt

Join two files on the first column (like a SQL join):

awk 'NR==FNR {name[$1]=$2; next} $1 in name {print $0, name[$1]}' users.txt orders.txt

Swap two columns in a CSV file:

awk -F, -v OFS=, '{t=$1; $1=$2; $2=t; print}' data.csv

Gotchas

  • Single quotes, always. In double quotes the shell replaces $1 with its own first argument before awk runs. Pass shell values with -v name="$value".
  • mawk vs gawk. On Debian and Ubuntu, awk is mawk: strftime exists in recent mawk, but -i inplace, --csv, asort, gensub and PROCINFO are gawk-only. Call gawk explicitly in scripts that rely on them.
  • -F' ' is special. A single space means "runs of whitespace" (the default). For a literal single space use -F'[ ]'.
  • Strings vs numbers. $5 > 80 on "85%" compares as a string. Add +0 ($5+0 > 80) to force a numeric comparison.
  • for (k in arr) order is unspecified. Pipe to sort, or in gawk set PROCINFO["sorted_in"]="@ind_str_asc".
  • Plain -F, is not a CSV parser. Quoted fields with commas break it. Use gawk --csv (5.3+) or a real CSV tool.
  • Modifying a field rebuilds the line. After $3="x", $0 is rejoined with OFS, so original spacing is lost.

More text tools: grep cheat sheet, sed cheat sheet, and the bash scripting tutorial for putting them in scripts. Reference: the GNU awk user's guide.

Frequently asked questions

How do I print a specific column with awk?

Use awk '{print $2}' file for the second whitespace-separated column. $0 is the whole line and $NF is the last column.

How do I change the field separator in awk?

Use -F: awk -F: '{print $1}' /etc/passwd. For output, set OFS, for example awk -F: -v OFS=',' '{print $1,$7}'.

How do I sum a column with awk?

awk '{s += $3} END {print s}' file adds up the third column and prints the total after the last line.

Is awk the same as gawk?

awk is the language; gawk (GNU awk) is one implementation. Fedora, Arch and openSUSE use gawk as awk; Debian and Ubuntu install mawk by default, which lacks some gawk extensions. Install the gawk package if you need them.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.