Skip to content

/commands/awk/awk-print-column

awk '{print $2}': print a specific column

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · GNU Awk 5.4.1updated
tool
awk
versions
GNU Awk 5.x, POSIX awk
os
linux, macos, windows

awk '{print $2}' file prints the second column of every line. By default awk splits each line on runs of spaces and tabs, ignoring leading blanks, and numbers the fields $1, $2, ...; $0 is the whole line and $NF the last field. For other separators set -F, for example awk -F, '{print $2}' file.csv or awk -F: '{print $1}' /etc/passwd.

Examples

bash
printf 'alice  admin   42\nbob    dev     37\ncarol  ops     29\n' > users.txt
echo '--- second column'
awk '{print $2}' users.txt
echo '--- first and third, separated by a comma'
awk '{print $1 "," $3}' users.txt
echo '--- last column'
awk '{print $NF}' users.txt
echo '--- columns with a header and a condition'
awk 'BEGIN {print "name age"} $3 > 30 {print $1, $3}' users.txt

Output

--- second column
admin
dev
ops
--- first and third, separated by a comma
alice,42
bob,37
carol,29
--- last column
42
37
29
--- columns with a header and a condition
name age
alice 42
bob 37

print $1, $3 (with a comma) separates fields with the output field separator OFS, a single space by default; print $1 $3 (no comma) joins them with nothing in between.

Other separators

bash
printf 'id,name,city\n1,Ada,London\n2,Linus,Helsinki\n' > people.csv
awk -F, '{print $2}' people.csv
echo '---'
awk -F, -v OFS='\t' 'NR > 1 {print $3, $2}' people.csv
echo '---'
echo 'root:x:0:0:root:/root:/bin/bash' | awk -F: '{print $1, $7}'

Output

name
Ada
Linus
---
London	Ada
Helsinki	Linus
---
root /bin/bash

Common tasks

CommandPrints
awk '{print $2}'Second field
awk '{print $NF}'Last field
awk '{print $(NF-1)}'Second to last field
awk 'NR > 1 {print $1}'First field, skipping the header line
awk '{$1=""; print}'Every field except the first (leaves a leading space)
awk -F'\t' '{print $3}'Third field of a tab-separated file

A range of columns, or a column by name

bash
printf 'id name city country\n1 Ada London UK\n2 Linus Helsinki FI\n' > t.txt
echo '--- columns 2 to the end'
awk '{ for (i = 2; i <= NF; i++) printf "%s%s", $i, (i < NF ? OFS : ORS) }' t.txt
echo '--- the column named city'
awk -v col=city 'NR == 1 { for (i = 1; i <= NF; i++) if ($i == col) c = i; next } { print $c }' t.txt

Output

--- columns 2 to the end
name city country
Ada London UK
Linus Helsinki FI
--- the column named city
London
Helsinki

Pitfalls

  • Double quotes around the program. The shell expands $2 before awk runs; the program becomes {print } and every line is printed in full. Use single quotes.
  • Windows line endings. A file saved with CRLF keeps a \r at the end of the last field, so $NF looks right on screen but comparisons such as $NF == "UK" fail. Strip it with tr -d '\r' or sub(/\r$/, "").
  • Empty fields. With the default separator, runs of blanks count as one separator, so an empty column in an aligned report disappears and later columns shift left. Fixed-width data needs substr() or GNU awk's FIELDWIDTHS.
  • Unquoted file names. A space in a path splits it into two arguments and awk stops with cannot open file for reading. For quoting mistakes inside the program, see awk syntax error.

To add up a column instead of printing it, see awk sum column; for separators in depth, awk -F.

cut -d, -f2 file is an alternative for a single-character delimiter, but cut treats each space as a separator, so it does not handle the aligned columns in users.txt the way awk does.

FAQ

Why does awk "{print $2}" print the whole line?

In double quotes the shell replaces $2 with its own second positional parameter, usually empty, so awk runs { print } and prints every line. Put the program in single quotes.

How do I print columns 3 to the end?

Loop over the fields, for example awk '{ for (i = 3; i <= NF; i++) printf "%s%s", $i, (i < NF ? OFS : ORS) }' file, or with GNU coreutils use cut -d' ' -f3- when the separator is a single space.

Can awk print a column by its header name?

Yes. Read the header in the first line, store the index of the wanted name, then print that field on the other lines, as in the example on this page.

Sources