Skip to content

AWK Print Column: $1, $NF, Last Column and More

How to print a column with AWK: $1, the last column with $NF, ranges, columns by header name and common pitfalls. Copy-paste examples tested on gawk and mawk.

Dasun Kalupahana 4 min read 78 views 0 comments
On this page
  1. The quick answer
  2. Sample files
  3. Print one or more columns
  4. Choose the delimiter
  5. The last column and the one before it
  6. Print everything except the first column
  7. Skip the header and filter rows
  8. Pick a column by its header name
  9. Take the column number from a shell variable
  10. Unique values from a column
  11. Problems and fixes
  12. The column has spaces inside it
  13. Parsing ls -l output
  14. A blank line crashes $(NF-1)
  15. Files from Windows (CRLF line endings)
  16. CSV fields with commas inside quotes
  17. Frequently asked questions
  18. How do I print the last column in AWK?
  19. How do I print columns 2 to 4?
  20. How do I print a column when the delimiter is a comma?
  21. What is the difference between print $1, $2 and print $1 $2?

Pulling one column out of a text file is the most common thing people use AWK for. It takes one short command, but a few small details decide whether you get the right column, a broken one, or a crash on a blank line. This guide covers the command, the options around it, and the mistakes worth knowing about, with sample input and the exact output of each example.

The quick answer

awk '{print $2}' file.txt          # second column, split on spaces and tabs
awk -F, '{print $2}' file.csv      # second column of a comma-separated file
awk '{print $NF}' file.txt         # last column

$1 is the first column, $2 the second, and $NF the last one. If you are new to AWK, read the AWK beginner's guide first for how lines and fields work.

Sample files

Create these once and every example below will work as shown. sales.csv is the same file used in the rest of this series.

echo 'a b c d' > w.txt

cat > sales.csv <<'EOF'
date,region,product,qty,price
2026-10-01,north,pen,10,1.50
2026-10-01,south,book,3,12.00
2026-10-02,north,book,2,12.00
2026-10-02,east,pen,25,1.50
2026-10-03,south,pen,5,1.50
EOF

cat > df.txt <<'EOF'
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   20G   28G  42% /
tmpfs           2.0G     0  2.0G   0% /dev/shm
/dev/sdb1       200G  120G   70G  63% /data
EOF
awk '{print $2}' w.txt          # b
awk '{print $1, $3}' w.txt      # a c
awk '{print $1 $3}' w.txt       # ac
awk '{print $1 "-" $3}' w.txt   # a-c

A comma inside print inserts the output separator, which is a space by default. Without the comma the values are glued together. If you want to join them with something else, either put your own text between them (the last line) or change the output separator once in a BEGIN block:

awk 'BEGIN {OFS=","} {print $1, $3}' w.txt    # a,c

Choose the delimiter

AWK splits on runs of spaces and tabs unless you tell it otherwise. Use -F for anything else:

awk -F, '{print $2}' sales.csv                 # CSV: region, north, south ...
awk -F: '{print $1, $NF}' <<< 'root:x:0:0:root:/root:/bin/bash'
# root /bin/bash
awk -F'\t' '{print $2}' file.tsv               # tab-separated

The <<< in the second example is a bash and zsh here-string that feeds a short text to the command; in plain sh, use echo '...' | awk ... instead. The details of separators, including several at once, are in the field separator guide.

The last column and the one before it

NF is the number of fields on the current line, so $NF is the last field and $(NF-1) is the one before it. This works even when lines have different numbers of columns:

awk '{print $NF}' w.txt         # d
awk '{print $(NF-1)}' w.txt     # c

The parentheses matter. Without them, AWK reads $NF-1 as "the last field, minus one":

echo '5 10' | awk '{print $NF-1}'     # 9, not the 5

There is no "all but the first" shortcut, but there are three ways to do it. Setting $1 to an empty string leaves a stray leading space, because AWK rebuilds the line with its output separator:

awk '{ $1=""; print }' w.txt                  # " b c d"  (note the leading space)
awk '{ $1=""; print substr($0,2) }' w.txt     # b c d

The loop version has no such problem, and it also lets you print any range of columns:

awk '{ for (i=2; i<=NF; i++) printf "%s%s", $i, (i<NF ? OFS : ORS) }' w.txt
# b c d

printf 'a b c d e f\n' | awk -v from=2 -v to=4 \
  '{ for (i=from; i<=to; i++) printf "%s%s", $i, (i<to ? OFS : ORS) }'
# b c d

Skip the header and filter rows

Put a condition in front of the braces. NR>1 skips the first line; a field test keeps only some rows:

awk 'NR>1 {print $1, $5}' df.txt
# /dev/sda1 42%
# tmpfs 0%
# /dev/sdb1 63%

awk -F, '$2=="north" {print $3}' sales.csv
# pen
# book

Pick a column by its header name

Counting columns gets fragile when someone adds one to the file. If the first line is a header, you can look columns up by name instead. Read the header into an array on line 1, then use the array as the column number:

awk -F, 'NR==1 {for (i=1; i<=NF; i++) col[$i]=i; next}
         {print $col["product"], $col["price"]}' sales.csv
pen 1.50
book 12.00
book 12.00
pen 1.50
pen 1.50

next tells AWK to stop processing the header line and move on to the next one. If the file gains a new column, this command keeps working.

Take the column number from a shell variable

awk -v col=3 '{print $col}' w.txt     # c

Because the number comes from outside, one script can print a different column each time, for example awk -v col="$1" '{print $col}' file.txt inside a shell script.

Unique values from a column

awk -F, 'NR>1 {print $2}' sales.csv | sort -u
# east
# north
# south

awk -F, 'NR>1 && !seen[$2]++ {print $2}' sales.csv     # keeps first-seen order
# north
# south
# east

Problems and fixes

The column has spaces inside it

With the default splitting, a tab-separated file where a name contains a space gives you half the name:

printf 'id\tname\tcity\n1\tAda Lovelace\tLondon\n' | awk 'NR>1 {print $2}'
# Ada

printf 'id\tname\tcity\n1\tAda Lovelace\tLondon\n' | awk -F'\t' 'NR>1 {print $2}'
# Ada Lovelace

Set the separator to a tab with -F'\t'.

Parsing ls -l output

A file name with a space is split into several fields, so $9 returns only the first word and $NF returns only the last one. In my test, a file called my report.txt gave my for $9 and report.txt for $NF. Do not parse ls output when names may contain spaces; use find or a shell glob instead.

A blank line crashes $(NF-1)

On an empty line NF is 0, so $(NF-1) asks for field -1. Both gawk and mawk stop with an error and exit code 2 (gawk says "attempt to access field -1", mawk says "negative field index $-1"). On a line with only one field, $(NF-1) is $0, the whole line. Guard it with a condition:

awk 'NF>1 {print $(NF-1)}' file.txt

Files from Windows (CRLF line endings)

Each line ends in a hidden carriage return, which becomes part of the last field. od -c shows it:

awk -F, '{print $NF "|"}' crlf.csv | od -c
# b  \r   |  \n

Remove it first:

awk -F, '{sub(/\r$/,""); print $NF "|"}' crlf.csv
# b|
# d|

CSV fields with commas inside quotes

Splitting on -F, cannot know that "hi, there" is one value. On the line Ada,"hi, there", field 2 is "hi and field 3 is there". For real CSV files you need a parser; this is covered in the CSV article of this series.

Frequently asked questions

How do I print the last column in AWK?

Use $NF. For the second to last, use $(NF-1).

How do I print columns 2 to 4?

Use the range loop shown above, with from=2 and to=4.

How do I print a column when the delimiter is a comma?

Add -F,, for example awk -F, '{print $3}' file.csv.

What is the difference between print $1, $2 and print $1 $2?

The comma puts the output separator (a space by default) between the values. Without it they are joined with nothing in between.

Free resources for this topic

Code snippets and fixes for this topic

Get one practical tip every week

New tutorials, fixes and free cheat sheets from DEV Talk, straight to your inbox. No spam, unsubscribe in one click.

Have a question about this post?

Ask the community: other developers and the author can answer.

Ask the community

Get notified about new articles

One click, no email needed. Turn it off anytime with the bell at the top.

Get new articles on your iPhone

Add DEV Talk to your Home Screen, open it, then tap the bell.

Rate this post
0.0
Share

Enjoying the content?

If this article helped you, you can support the author with a coffee. It keeps new posts coming.

Buy me a coffee (opens in a new tab)

Comments 0

Be kind. Comments with links are reviewed before they appear.

No comments yet

Be the first to share your thoughts.

Get new articles in your inbox

Practical tutorials and deep dives, about once a week. No spam, unsubscribe anytime.

Privacy policy

Add DEV Talk to your Home Screen

  1. 1 Tap the Share button in Safari's toolbar.
  2. 2 Scroll down and tap Add to Home Screen.
  3. 3 Tap Add. Open it from the Home Screen to read like an app and to turn on notifications with the bell.

We use cookies to improve your experience and analyze traffic. By continuing, you agree to our Privacy Policy.