Cheat Sheet

awk Command Examples

awk splits every line into fields and runs your code on the lines you select, which makes it the tool for columns: print them, filter on them, do math on them. Every row on this sheet is a real example you can paste into a shell.

Last updated September 11, 2026

Fields split on whitespace by default. is the first field, the last, the whole line.

CommandWhat it does
First column of every line
Two columns, separated by a space
Last column
Second-to-last column
Mix fields with literal text
PID and command from ps
Size and name from ls
Number every line

Column Ranges

Printing everything except one column is the awkward case, because awk has no slice syntax.

CommandWhat it does
A fixed range of columns
All but the first field (leaves a leading space)
All but the first field, leading space trimmed
All but the last field
Drop the last field (gawk and mawk)
Field 3 to end of line, original spacing kept

Assigning to a field rebuilds with , so flattens any column padding the file had. The / form avoids that, at the cost of matching the wrong spot if that text also appears earlier in the line. For an arbitrary start column, loop:

awk '{for (i = 3; i <= NF; i++) printf "%s%s", $i, (i < NF ? OFS : ORS)}' file

Field Separators

sets the input separator; is what goes between fields on output.

CommandWhat it does
Comma-separated input
Tab-separated input
Every username on the system
The separator can be a regex: comma or semicolon
Comma with optional spaces around it
Same as -F, set inside the program
Convert CSV to TSV ( forces the rebuild)
Custom output separator

NR and NF

is the current line number, the number of fields on the line. Both double as filters.

CommandWhat it does
Print line 5 only
Skip the header line
A line range
Every second line
Count lines, like wc -l
How many fields each line has
Drop blank lines (0 fields is false)
Only lines with exactly 7 fields (catch bad CSV rows)
FNR resets per file; print each file's name once

Patterns and Conditions

The shape is : the action runs on lines where the pattern holds. Either half can be omitted.

CommandWhat it does
Lines matching a regex (like grep)
Column 2 of matching lines
Lines NOT matching
Exact string match on a field
Numeric comparison on a field
Regex match on one field only
Field does not match
Combine with && and ||
Range: from one match to the next
Disk usage percent per mount

if/else lives inside the action:

awk '{if ($3 > 100) print $1 " high"; else print $1 " ok"}' data.txt
awk '{print $1, ($3 > 100 ? "high" : "ok")}' data.txt

Loops and Control Flow

CommandWhat it does
One field per line
Loop with no input at all
Same loop, while form
Skip a line and read the next one
Stop at the first hit (fast on huge files)
Bail out early instead of reading the rest
Set the shell exit status from awk

skips the remaining rules for that line; jumps straight to , so an block still runs after it.

BEGIN and END

runs before the first line, after the last: headers, totals, averages.

CommandWhat it does
Sum a column (the classic)
Average of a column
Maximum of a column
Count matches ( prints 0 instead of blank)
Add a header line
BEGIN is where FS/OFS setup goes

printf

formats output with C-style specifiers and adds no newline unless you write .

CommandWhat it does
String, one per line
Left-pad to 15, right-pad to 8: aligned columns
Two decimal places
Integer plus a literal percent sign
Mix strings and numbers
Decimal to hex ( for octal)
Big numbers without scientific notation
Works in END too

on a number over about 16 digits falls back to and prints ; or keeps the digits.

Quoting and Output

CommandWhat it does
Everything on one line, no newline per record
Wrap a field in double quotes
Same thing without escaping
Put a literal tab between fields
Strip Windows carriage returns
Write to a file from inside awk
Append instead of overwriting
Split input into one file per column-1 value

inside the program is awk's redirect, not the shell's, so it needs no quoting beyond the single quotes already around the program. awk keeps every file it writes open, so splitting into thousands of files needs .

Arrays and Counting

awk arrays are string-keyed maps, which makes counting and grouping one-liners.

CommandWhat it does
Count occurrences of each value in column 1
Remove duplicate lines, order preserved (uniq without sort)
First line per distinct column-1 value
Sum column 2 per key in column 1
Keys that appear more than once

The count-and-sort pipeline for "top talkers" in a log (see the grep cheat sheet for the pure-grep half):

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

String Functions

CommandWhat it does
Line length in characters
Lines longer than 80 characters
First 3 characters of field 1
Change case
Position of a substring (0 if absent)
Split a field on and use a piece
Replace first match: trim leading spaces
Replace all matches, here only in field 3
Print only the matched text, like grep -o
Format into a string

and modify in place and return the replacement count. For pure stream find-and-replace, sed is usually the shorter tool.

Variables

CommandWhat it does
Pass a value in with -v
Pass a shell variable in safely
Match against a variable (in a script)
Read environment variables directly
Output record separator: join lines with commas
Paragraph mode: records split on blank lines

Shell Commands from awk

awk can shell out mid-program, which covers the jobs a pipeline alone cannot.

CommandWhat it does
Run a shell command once per line
Capture a command's output into a variable
Pipe awk's own output into a command
Read a command's output line by line
Find PIDs and kill them

A command stays open after the first read, so running it again in the same program returns nothing until you .

Scripts and Recipes

Past one line, put the program in a file and run it with , or give it a shebang.

awk -f report.awk access.log
#!/usr/bin/awk -f
BEGIN { FS = ","; print "user,total" }
NR > 1 { total[$1] += $3 }
END { for (u in total) print u "," total[u] }

Everyday pipelines:

CommandWhat it does
Processes over 50% CPU
Mounts over 80% full ( strips the %)
Memory in use
Listening addresses and ports
Human (non-system) users

Gotchas

  • Single-quote the program. In double quotes the shell expands before awk runs, which silently breaks the script.
  • means no awk is installed, which happens on slim containers: or . A almost always means the shell ate part of the program, so check the quoting before the logic.
  • Not all awks are equal: Linux usually has gawk or mawk, macOS ships an older BSD awk. , , and -style classes are gawk extras; everything on this sheet sticks to the portable core.
  • Comparisons are type-sensitive: compares numbers, but if the field has stray characters awk may compare strings. Force a number with .
  • Assigning to any field (even ) rebuilds with OFS, which rewrites the separators on output. Sometimes that is exactly what you want; sometimes it is the bug.
  • Uninitialized variables are and 0 at the same time, so needs no setup, and a missing field prints as empty rather than erroring.
  • grep selects lines and sed rewrites them; see the grep cheat sheet and sed cheat sheet for the other two thirds of the toolkit.

awk FAQ

What does awk stand for?

The initials of its three authors: Alfred Aho, Peter Weinberger, and Brian Kernighan, who wrote it at Bell Labs in 1977. It is said like the bird, not spelled out. The name matters in practice because awk on your machine is usually a link to someone else's rewrite: gawk on most Linux distributions, mawk on Debian and Ubuntu by default, and the original one-true-awk on macOS. That is why a gawk-only function such as gensub() works on your server and fails on your laptop.

How does the awk command work?

It reads input one record (a line by default) at a time, splits that record into fields on FS, then tests every pattern in your program against it and runs the action of each one that matches. BEGIN fires before the first read, END after the last. That loop explains the shorthands: NR counts records for free, a pattern with no action gets the default {print}, and an action with no pattern runs on every line. It also explains why awk needs no loop of its own for most jobs.

What is the difference between cut and awk?

cut splits on one literal character and never collapses repeated ones, so cut -d' ' -f2 falls apart on ls -l or ps output where the columns are padded with variable spacing. awk's default separator is any run of whitespace, so awk '{print $2}' just works. cut also emits fields in file order however you list them, while awk prints them in the order you write. cut stays faster on huge single-delimiter files, which is the one place it still wins.

How do I sort awk output?

awk has no output ordering of its own. for (k in arr) walks keys in an order you cannot predict, which is why counting one-liners come out shuffled. Pipe the result to sort instead: awk '{c[$1]++} END {for (k in c) print c[k], k}' log | sort -rn. gawk can sort in-process with PROCINFO["sorted_in"] = "@val_num_desc" or asort(), but neither exists in mawk or the BSD awk on macOS, so the pipe stays the portable answer.

How do I use awk in a shell script?

Single-quote the program so the shell leaves $1 alone, and hand shell values in with -v rather than splicing them into the program text, which breaks the first time a value contains a quote. Anything after the program is treated as a filename, not an argument, which is the usual surprise. Past a few lines, move the program into its own .awk file and run awk -f report.awk data.txt, or give the file a #!/usr/bin/awk -f shebang and make it executable.

Related cheat sheets