How to use grep in Linux to locate files with AND, NOT, OR operators

Over the years, I've learned to love the Linux command-line. There's just something about being able to type fast and hacker-ish!

The grep tool in Linux is a command-line filter that allows files to be searched with certain characters or patterns. Once the character/pattern is found, grep displays any line with the contents. Grep supports operators like AND (-E), OR (-e), and NOT (-v).

For a full command-list, visit GeeksforGeeks grep page. They have some great examples.

This post is going to cover parameters like -e and -v simply because I find those easiest for beginners. There are other ways to use grep which you may like better.

How to use the grep NOT operator

For this example, let's use df -h to see how much free space I have on some of my samba shares. I can use grep to get rid of tmpfs directories and loop mounts. After typing df -h, here is my list.

Filesystem          Size  Used Avail Use% Mounted on
udev                 32G     0   32G   0% /dev
tmpfs               6.3G  3.5M  6.3G   1% /run
/dev/sda2           117G   25G   86G  23% /
tmpfs                32G  340K   32G   1% /dev/shm
tmpfs               5.0M     0  5.0M   0% /run/lock
tmpfs                32G     0   32G   0% /sys/fs/cgroup
/dev/loop1           56M   56M     0 100% /snap/core18/2074
/dev/loop2          219M  219M     0 100% /snap/gnome-3-34-1804/66
/dev/loop3          219M  219M     0 100% /snap/gnome-3-34-1804/72
/dev/loop5           65M   65M     0 100% /snap/gtk-common-themes/1514
/dev/loop6           51M   51M     0 100% /snap/snap-store/547
/dev/loop4           52M   52M     0 100% /snap/snap-store/518
/dev/loop0           56M   56M     0 100% /snap/core18/1988
/dev/loop7           66M   66M     0 100% /snap/gtk-common-themes/1515
/dev/loop8           32M   32M     0 100% /snap/snapd/11036
/dev/loop9           33M   33M     0 100% /snap/snapd/12398
/dev/sda1           511M  7.9M  504M   2% /boot/efi
/dev/md127          7.3T  6.9T   27G 100% /home/nick/chia11
tmpfs               6.3G   12K  6.3G   1% /run/user/1000
//10.4.13.4/chia4   3.6T  3.6T   35G 100% /home/nick/chia4
//10.4.13.4/pool01   23T  6.9T   16T  31% /home/nick/pool01
//10.4.13.4/sc200    29T   29T   17G 100% /home/nick/sc200
tmpfs               6.3G   44K  6.3G   1% /run/user/125

Pass the -v parameter to grep to remove what you don't want

Use df -h | grep -v /dev to remove all of the mounts that start with /dev. In my case, this helps eliminate the loop directories and snap stuff. The new output contains everything else.

Filesystem          Size  Used Avail Use% Mounted on
tmpfs               6.3G  3.5M  6.3G   1% /run
tmpfs               5.0M     0  5.0M   0% /run/lock
tmpfs                32G     0   32G   0% /sys/fs/cgroup
tmpfs               6.3G   12K  6.3G   1% /run/user/1000
//10.4.13.4/chia4   3.6T  3.6T   35G 100% /home/nick/chia4
//10.4.13.4/pool01   23T  7.0T   16T  31% /home/nick/pool01
//10.4.13.4/sc200    29T   29T   17G 100% /home/nick/sc200
tmpfs               6.3G   44K  6.3G   1% /run/user/125

How to use the grep OR operator

To filter our records (lines) even more, we can use the -e parameter with what we've already used. This can be paired with an existing parameter to use both (i.e. -ve instead of just -v.

Pass the -e parameter to grep to remove even more

With the command df -h | grep -ve /dev -e tmpfs, not only do we remove the /dev directories, but also anything containing tmpfs.

The new output containing our filtered results! Just what I need to see my disk space.

Filesystem          Size  Used Avail Use% Mounted on
//10.4.13.4/chia4   3.6T  3.6T   35G 100% /home/nick/chia4
//10.4.13.4/pool01   23T  7.0T   16T  32% /home/nick/pool01
//10.4.13.4/sc200    29T   29T   17G 100% /home/nick/sc200

The above shows my filesystem with any mounted drives that I need to check for available space and how much I'm using.

How to use the grep AND operator

Technically speaking, there isn't a grep AND operator, but we can simulate it with the -E parameter. Use this with patterns.

Pass the -E parameter and a pipe | to grep for more than one result

Let's say I'm looking for my home directory /home/nick AND a mount containing /dev. I can use df -h | grep /dev | grep /home/nick to display a line with both of these.

/dev/md127          7.3T  6.9T   27G 100% /home/nick/chia11

Notice it's only one result! It contains both a mount /dev/md127 and also the directory it is mount to /home/nick/chia11.