cut
cut
is a handy tool for many field processing use cases. The features are limited compared to awk
and perl
commands, but the reduced scope also leads to faster processing.
Individual field selections
By default, cut
splits the input content into fields based on the tab character. You can use the -f
option to select a desired field from each input line. To extract multiple fields, specify the selections separated by the comma character.
# second field
$ printf 'apple\tbanana\tcherry\n' | cut -f2
banana
# first and third field
$ printf 'apple\tbanana\tcherry\n' | cut -f1,3
apple cherry
cut
will always display the selected fields in ascending order. Field duplication will be ignored as well.
# same as: cut -f1,3
$ printf 'apple\tbanana\tcherry\n' | cut -f3,1
apple cherry
# same as: cut -f1,2
$ printf 'apple\tbanana\tcherry\n' | cut -f1,1,2,1,2,1,1,2
apple banana
By default, cut
uses the newline character as the line separator. cut
will add a newline character to the output even if the last input line doesn't end with a newline.
$ printf 'good\tfood\ntip\ttap' | cut -f2
food
tap
Field ranges
You can use the -
character to specify field ranges. You can skip the starting or ending range, but not both.
# 2nd, 3rd and 4th fields
$ printf 'apple\tbanana\tcherry\tdates\n' | cut -f2-4
banana cherry dates
# all fields from the start till the 3rd field
$ printf 'apple\tbanana\tcherry\tdates\n' | cut -f-3
apple banana cherry
# all fields from the 3rd field till the end
$ printf 'apple\tbanana\tcherry\tdates\n' | cut -f3-
cherry dates
Input field delimiter
Use the -d
option to change the input delimiter. Only a single byte character is allowed. By default, the output delimiter will be same as the input delimiter.
$ cat scores.csv
Name,Maths,Physics,Chemistry
Ith,100,100,100
Cy,97,98,95
Lin,78,83,80
$ cut -d, -f2,4 scores.csv
Maths,Chemistry
100,100
97,95
78,80
# use quotes if the delimiter is a shell metacharacter
$ echo 'one;two;three;four' | cut -d; -f3
cut: option requires an argument -- 'd'
Try 'cut --help' for more information.
-f3: command not found
$ echo 'one;two;three;four' | cut -d';' -f3
three
Output field delimiter
Use the --output-delimiter
option to customize the output separator to any string of your choice. The string is treated literally. Depending on your shell you can use ANSI-C quoting to allow escape sequences.
# same as: tr '\t' ','
$ printf 'apple\tbanana\tcherry\n' | cut --output-delimiter=, -f1-
apple,banana,cherry
# multicharacter example
$ echo 'one;two;three;four' | cut -d';' --output-delimiter=' : ' -f1,3-
one : three : four
# ANSI-C quoting example
# depending on your environment, you can also press Ctrl+v and then Tab key
$ echo 'one;two;three;four' | cut -d';' --output-delimiter=$'\t' -f1,3-
one three four
# newline as the output field separator
$ echo 'one;two;three;four' | cut -d';' --output-delimiter=$'\n' -f2,4
two
four
Complement
The --complement
option allows you to invert the field selections.
# except second field
$ printf 'apple ball cat\n1 2 3 4 5' | cut --complement -d' ' -f2
apple cat
1 3 4 5
# except first and third fields
$ printf 'apple ball cat\n1 2 3 4 5' | cut --complement -d' ' -f1,3
ball
2 4 5
Suppress lines without delimiters
By default, lines not containing the input delimiter will still be part of the output. You can use the -s
option to suppress such lines.
$ cat mixed_fields.csv
1,2,3,4
hello
a,b,c
# second line doesn't have the comma separator
# by default, such lines will be part of the output
$ cut -d, -f2 mixed_fields.csv
2
hello
b
# use -s option to suppress such lines
$ cut -sd, -f2 mixed_fields.csv
2
b
$ cut --complement -sd, -f2 mixed_fields.csv
1,3,4
a,c
If a line contains the specified delimiter but doesn't have the field number requested, you'll get a blank line. The -s
option has no effect on such lines.
$ printf 'apple ball cat\n1 2 3 4 5' | cut -d' ' -f4
4
Character selections
You can use the -b
or -c
options to select specified bytes from each input line. The syntax is same as the -f
option. The -c
option is intended for multibyte character selection, but for now it works exactly as the -b
option. Character selection is useful for working with fixed-width fields.
$ printf 'apple\tbanana\tcherry\n' | cut -c2,8,11
pan
$ printf 'apple\tbanana\tcherry\n' | cut -c2,8,11 --output-delimiter=-
p-a-n
$ printf 'apple\tbanana\tcherry\n' | cut -c-5
apple
$ printf 'apple\tbanana\tcherry\n' | cut --complement -c13-
apple banana
$ printf 'cat-bat\ndog:fog\nget;pet' | cut -c5-
bat
fog
pet
NUL separator
Use -z
option if you want to use NUL character as the line separator. In this scenario, cut
will ensure to add a final NUL character even if not present in the input.
$ printf 'good-food\0tip-tap\0' | cut -zd- -f2 | cat -v
food^@tap^@
Alternatives
Here's some alternate commands you can explore if cut
isn't enough to solve your task.