2

I have a directory with several subdirectories; in each of these, I have some files. I want to perform a grep only for some subdirectories to find those files that match the query and remove them; something like grep -rl --exclude-dir=dir1 --exclude-dir=dir2 HUMAN . | rm, but I'd prefer not to parse the stdin from grep.

I think I have to combine find and rm, but I don't know how.

Moreover, it seems that (at least here in Cygwin), I cannot do --exclude-dir={dir1, dir2}, I have to split them. This is a minor problem, but does someone have any idea why this doesn't work?

LinuxBlanket
  • 345
  • 1
  • 3
  • 13
  • 2
    What do you mean by "I cannot do"? `--exclude-dir={dir1,dir2}` works fine for me in `bash`, just remove the space after the comma. – choroba Mar 14 '16 at 15:02
  • Using `find` you can reference one file using `{}` within the `-exec` option, eg: `find . -type f -name *.jar -exec ls -l {} \;` searches for all jar-Files and executes a `ls -l ` for each file. *Disclaimer*: I tried it with CentOS, not with cygwin – mnille Mar 14 '16 at 15:19

1 Answers1

2
grep -rlZ --exclude-dir=dir1 --exclude-dir=dir2 HUMAN . |
  xargs -r0 rm -f

If you want find to do the directory traversal:

find . -type d \( -name dir1 -o -name dir2 \) -prune -o \
  -type f -exec grep -lZ HUMAN {} + |
  xargs -r0 rm -f

Portably/standardly, that would have to be:

find . -type d \( -name dir1 -o -name dir2 \) -prune -o \
  -type f -exec grep -q HUMAN {} \; -exec rm -f {} +

but that means running one grep per file.

For --exclude-dir={dir1,dir2} to work, you need a shell with brace expansion support like csh, tcsh, ksh, zsh, bash or fish.

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501