samthegolden
samthegolden

Reputation: 1490

How to exclude nested directories in grep command?

I want to search for the word disable_mlock in the current directory and its subfolders. For that, I use:

sam@sam-Dell:~/Desktop$ grep -r disable_mlock
a/vault/config/vault-config.hcl:disable_mlock=true
b/vault/config/vault-config.hcl:disable_mlock=true
vault/config/vault-config.hcl:disable_mlock=true

Then, I would like to exclude only the vault/config/ subdirectory:

sam@sam-Dell:~/Desktop$ grep -r --exclude-dir=vault/config/
a/vault/config/vault-config.hcl:disable_mlock=true
b/vault/config/vault-config.hcl:disable_mlock=true
vault/config/vault-config.hcl:disable_mlock=true

And it does not work.

Then I try to exclude only the vault/ dir:

sam@sam-Dell:~/Desktop$ grep -r disable_mlock --exclude-dir=vault
sam@sam-Dell:~/Desktop$

It returns nothing... probably because vault/ is in the path of every result.

If I exclude config/:

sam@sam-Dell:~/Desktop$ grep -r disable_mlock --exclude-dir=config/
sam@sam-Dell:~/Desktop$

No result appears, too - all of the matches were below a config/ directory. But I just want to exclude one of those config/ dirs, the vault/config/, not all of them!

I conclude grep can only exclude one directory at a time, whether a direct one or a deep one, relatively to the current directory. In this case it is an issue for me because I have paths that have similar directories.

I cannot find, then, a way of excluding specific nested subdirectories with grep. Is there a way to do it with grep?

Upvotes: 0

Views: 702

Answers (3)

Saeed Ahadian
Saeed Ahadian

Reputation: 222

I assume that you strictly want to use grep command which means no piping or other alternative commands that would work better. If you're in a hurry, check out the last code.

First of all, a word of caution! If you take a look at the man page of the grep command, you find this syntax for --exclude-dir option,

 --exclude-dir=PATTERN

It means that the option only accepts pattern as the input. You cannot use a pathname for it. That's why your search with --exclude-dir=vault/config didn't work. Because it didn't exclude the config subdirectory within the vault directory, it actually excludes every single directory that has 'vault/config' in its name which there is none.

So by knowing this, it simply means that the option is useless for this context. But we have to somehow extend the "clue" and let the command to know exactly which directories we want to search. First, take another look at grep command syntax,

grep [OPTION]... PATTERN [FILE]...

TL;DR The way I do this is,

grep -r disable_mlock ?/vault/config

I simply used an exclusive file pathname. The question mark (?) is a wildcard which stands for a "single character". That's because I know all the directories which I want to search in, have only one letter as their name.

Upvotes: 0

xhienne
xhienne

Reputation: 6134

GNU find provides more options than grep to exclude paths:

find -path ./vault/config -prune -o -type f -exec grep pattern {} +

-prune combined with -path path_expression instructs find to ignore the specified path. -exec grep ... does the actual search.

This command won't follow symbolic links, contrary to grep, which may or may not be a good thing, depending on your needs. Use the -L option if you need to follow them.

Upvotes: 0

NumZ
NumZ

Reputation: 69

Are you accept pipe in your command or do you want it in one shot? With pipe:

grep -r disable_mlock * | egrep -v "^vault"

Upvotes: 1

Related Questions