Objective: Perform grep
on one single column and if there’s a match, print the whole line.
Performing a grep on a multi-column input can be performed by either the grep
or the awk
utilities. Before we look at an example, let’s look at two different sample inputs – an output of ‘ls -l
‘ and the contents of the /etc/passwd
file. First, let’s look at the output of ‘ls -l
‘.
1 2 3 4 5 |
$ ls -l total 0 -rw-r--r-- 1 root root 0 Nov 14 15:55 file1 -rw-r--r-- 1 mysql root 0 Nov 14 15:55 file2 -rw-r--r-- 1 ibrahim staff 0 Dec 18 15:55 file3 |
Now, to grep for lines where the file owner is root, we will need to do a regex match on column 3. Below is an example to do that using grep
with extended regex support.
1 2 |
$ ls -l | grep -E "^\S+\s+\S+\s+root" -rw-r--r-- 1 root root 0 Nov 14 15:55 file1 |
With awk
, it is going to be something like this – we do a regex match on field 3 and if it’s a match, we print the whole line. An example is shown below.
1 2 |
$ ls -l | awk '$3 ~ /root/ { print $0 }' -rw-r--r-- 1 root root 0 Nov 14 15:55 file1 |
Let’s now look at the /etc/passwd
file. Below is a truncated output.
1 2 3 4 5 6 7 8 9 10 11 |
$ cat /etc/passed root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync ... mysql:x:101:103:MySQL Server,,,:/nonexistent:/bin/false ntp:x:106:113::/home/ntp:/bin/false ibrahim:x:1000:50::/home/ibrahim:/bin/bash ... |
To list all lines that have ‘/bin/false
‘ as the shell using grep
, we will need to do something like this.
1 2 3 |
$ cat /etc/passwd | grep '/bin/false$' mysql:x:101:103:MySQL Server,,,:/nonexistent:/bin/false ntp:x:106:113::/home/ntp:/bin/false |
With awk
, it’s a bit more straight forward – we define the field separator and perform a regex match on the 7th field.
1 2 3 |
$ cat /etc/passwd | awk -F":" '$7 ~ /bin\/false$/ { print $0 }' mysql:x:101:103:MySQL Server,,,:/nonexistent:/bin/false ntp:x:106:113::/home/ntp:/bin/false |
Personally, I prefer to use awk
to do pattern matching on a single column – the regular expression is only for the field that we are interested in. With grep
, the regular expression is normally for the whole line and not just for the column that we are interested in – so it tends to get a lot more complicated.