Print Columns
Fields split on whitespace by default. is the first field, the last, the whole line.
| Command | What 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 |
Field Separators
sets the input separator; is what goes between fields on output.
| Command | What 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.
| Command | What 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.
| Command | What 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.txtBEGIN and END
runs before the first line, after the last: headers, totals, averages.
| Command | What 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 .
| Command | What 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 | |
| Works in END too |
Arrays and Counting
awk arrays are string-keyed maps, which makes counting and grouping one-liners.
| Command | What 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 | headString Functions
| Command | What 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 | |
| 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
| Command | What 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 |
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:
| Command | What 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.
- 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.