Practical Guide to Linux's CUT Command
cut is a Unix command line used to extract sections from each line of input.
cut filters standard STDIN from another command or input file and sends the filtered output to STDOUT.
Let us first look to its help page:
$ man cut
or
$ cut --help
NAME
cut - remove sections from each line of files
DESCRIPTION
Print selected parts of lines from each FILE to standard output.
Mandatory arguments to long options are mandatory for short options too.
Usage: cut OPTION... [FILE]...
-b, --bytes=LIST select only these bytes
-c, --characters=LIST select only these characters
-d, --delimiter=DELIM use DELIM instead of TAB for field delimiter
-f, --fields=LIST select only these fields; also print any line that contains no delimiter character, unless the -s option is specified
-n with -b: don't split multibyte characters
--complement complement the set of selected bytes, characters or fields
-s, --only-delimited do not print lines not containing delimiters
--output-delimiter=STRING use STRING as the output delimiter the default is the input
Use one, and only one of -b, -c or -f. Each LIST is made up of one range, or many ranges separated by commas. Selected input is written in the same order that it is read, and is written exactly once. Each range is one of:
N N'th byte, character or field, counted from 1
N- from N'th byte, character or field, to end of line
N-M from N'th to M'th (included) byte, character or field
-M from first to M'th (included) byte, character or field
With no FILE, or when FILE is -, read standard input.
So typically we can extract line segments by bytes (-b), characters(-c) and fields (-f), separated by a delimiter (-d). Let's see each case.
Cut by Character
We used cut's -c option to print only specific range of characters:
$ echo echo hacker-school-is-awesome > cut.txt
$ cut -c 2 cut.txt
a
$ cut -c 3 cut.txt
c
$ cut -c -3 cut.txt
hac
$ cut -c -6 cut.txt
hacker
$ cut -c 6- cut.txt
r-school-is-awesome
To select a column of characters:
$ cut -c2 cut2.txt
a
b
c
Cut By Field
The default field used by cut command is TAB.
Let's create a file where common delimiter is TAB (to insert TAB on a command line, use ^V ( CTRL + V ) before you hit TAB):
$ echo "0 1 2" > cut.txt
$ echo "a b c" >> cut.txt
$ cat cut.txt
0 1 2
a b c
$ cut -f2- cut.txt
1 2
b c
$ cut -f1- cut.txt
0 1 2
a b c
$ cut -f3- cut.txt
2
c
A classic example of selecting more than one field:
$ grep "/bin/bash" /etc/passwd | cut -d':' -f1,6
root:/root
myname:/home/myname
We can also select all fields except the specified fields:
$ grep "/bin/bash" /etc/passwd | cut -d':' --complement -s -f7
root:x:0:0:root:/root
myname:1000:1000:myname:/home/myname
Delimiter Option
If we need to override the default behavior and instruct cut command to use different common delimiter the -d option becomes very handy.
$ echo h-a-c-k-e-r > cut.txt
$ echo s-c-h-o-o-l >> cut.txt
$ cat cut.txt
h-a-c-k-e-r
s-c-h-o-o-l
$ cut -d - -f1- cut.txt
h-a-c-k-e-r
s-c-h-o-o-l
$ cut -d - -f2- cut.txt
a-c-k-e-r
c-h-o-o-l
$ cut -d - -f3- cut.txt
c-k-e-r
h-o-o-l
$ cut -d - -f3 cut.txt
c
h
$ cut -d - -f-2 cut.txt
h-a
s-c
$ cut -d - -f-2,4 cut.txt
h-a-k
s-c-o
Useful Applications of CUT
Extract List of Users
We can extract the list of users on a current system from /etc/passwd
file:
$ cut -d : -f 1 /etc/passwd
root
bin
daemon
adm
...
Display Total Nemory on the Current System
$ free | grep Mem | sed 's/\s\+/,/g' | cut -d , -f2
5992256
Retrieve a CPU Type
$ cat /proc/cpuinfo | grep "name" | cut -d : -f2 | uniq
Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
Retrieve External IP Address
$ wget -q -O X http://ipchicken.com/
$ grep '^ \{8\}[0-9]' X | sed 's/\s\+/,/g' | cut -d , -f2
Get a MAC Address of my Network Interfaces
$ ifconfig eth0 | grep HWaddr | cut -d " " -f 11
List Users Logged in to a Current System
$ who | cut -d \s -f1
Show What Service is Using a Port
$ grep -w <PORT> /etc/services | cut -f 1 | uniq
Extracting Useful Information from PS
$ ps axu | grep google-chrome | sed 's/\s\+/ /g' | cut -d' ' -f2,11-
Output only the Permissions of the files
$ ls -l | cut -c2-10
Output only the Size and Name of Files
$ ls -l | tr -s ' ' ' ' | cut -f5,9 -d ' '