Linux command list

awk command: pick columns, filter rows, add them up

__ __ _ _____
\ \ / /__| |_|_ _|__ _ __ _ __ ___
\ \ /\ / / _ \ '_ \| |/ _ \ '__| '_ ` _ \
\ V V / __/ |_) | | __/ | | | | | |
\_/\_/ \___|_.__/|_|\___|_| |_| |_| |_
 
A sandbox for trying awk. Nothing here can touch your real files.
user@webterm:~/project$
 

awk splits each line into columns and works on them. Learn how `$1` picks a column, how a condition filters rows, and how `END` produces a total, by running the commands in a real terminal in your browser.

Updated: 2026-09-06

Syntax

awk 'condition { action }' file

Each line is split into columns on whitespace, and the action runs on matching lines.

Try it first

Take the first column, the IP address.

$ cat logs/access.log
10.0.0.1 /index 200 512
10.0.0.2 /missing 404 128
10.0.0.1 /index 200 640
10.0.0.3 /boom 500 96
10.0.0.2 /index 200 512
$ awk '{print $1}' logs/access.log
10.0.0.1
10.0.0.2
10.0.0.1
10.0.0.3
10.0.0.2

$1 is the first column, $2 the second. A comma between them prints a space.

$ awk '{print $1, $3}' logs/access.log
10.0.0.1 200
10.0.0.2 404
10.0.0.1 200
10.0.0.3 500
10.0.0.2 200

When lines have different numbers of columns, $NF, the last one, is handy.

$ awk '{print $NF}' logs/access.log
512
128
640
96
512

Filtering rows

A condition in front of the braces limits which lines are acted on.

$ awk '$3 == 200 {print $1}' logs/access.log
10.0.0.1
10.0.0.1
10.0.0.2

Leave out the action and matching lines print as they are.

$ awk '$3 == 200' logs/access.log
10.0.0.1 /index 200 512
10.0.0.1 /index 200 640
10.0.0.2 /index 200 512

Numbers can be compared, which is something grep cannot do.

$ awk '$4 > 500 {print $2, $4}' logs/access.log
/index 512
/index 640
/index 512

For text, put the pattern between slashes.

$ awk '/index/ {print $1}' logs/access.log
10.0.0.1
10.0.0.1
10.0.0.2

Totals and counts

END { ... } runs once, after every line has been read.

$ awk '{sum += $4} END {print sum}' logs/access.log
1888

Each line adds $4 to sum, and the total is printed at the end. For a line count, print NR.

$ awk 'END {print NR}' logs/access.log
5

Since NR is the current line number, it also skips headers.

Changing the separator

CSV needs -F.

$ awk -F, 'NR > 1 {print $2, $3}' users.csv
ada web
linus infra
grace infra

NR > 1 drops the header row.

When you actually reach for it

awk is what you type when the columns and a condition matter at the same time.

SituationWhat to type
Take one columnawk '{print $1}' access.log
Act on matching rows onlyawk '$3 == 500 {print $2}' access.log
Filter by a numberawk '$4 > 500' access.log
Add a column upawk '{sum += $4} END {print sum}' access.log
Work with CSV columnsawk -F, '{print $2}' users.csv

The rule of thumb against cut is short. Extracting only, use cut; conditions or arithmetic, use awk.

Things that trip people up

Wrap the script in single quotes. $1 means something to the shell too, so double quotes let the shell get there first. Always write awk '{print $1}'.

Extra spaces do not matter. awk treats a run of whitespace as one separator. Logs padded out to line up still give you the third column as $3.

It leads straight into counting.

$ awk '{print $1}' logs/access.log | sort | uniq -c | sort -nr
      2 10.0.0.2
      2 10.0.0.1
      1 10.0.0.3

Pick a column with awk, then let sort and uniq do the tallying.

A missing file says so.

$ awk '{print $1}' nothing.log
awk: nothing.log: No such file or directory

Practise it hands-on

webterm.appthis site

learn.webterm.appa separate site

>_WEBTERM LEARN

WebTerm Learn: from one command to actually using it

Commands stick when they show up in a real sequence of work, not one at a time. There is a course that builds them up in order.

See the course

Related commands

cut / sed / grep / sort

Frequently asked questions

When do I use awk instead of cut?
For pulling a column out as it is, `cut` is simpler. Reach for awk when you need a condition, a different column order, or arithmetic.
What are `$1` and `$NF`?
`$1` is the first column and `$2` the second. `$NF` is the last one and `$0` is the whole line. `NF` on its own is the number of columns.
What is `NR`?
The current line number. `NR > 1` skips a header row, and `END {print NR}` counts the lines.
What happens with a condition and no braces?
Matching lines are printed as they are, which makes `awk '$3 == 200'` behave a little like grep.
What if the separator is a comma?
Add `-F,`, as in `awk -F, '{print $2}' users.csv`. Tell awk the separator first, then name the columns.