I have large tree, with many pdf files in it. I want to delete the pdf files in this tree, but only those pdf files in sub folders named rules/ There are other type of files inside rules/. The rules/ subfolders have no other subfolders.

For example, I have this tree. Everything below 'source'

            rules/*.pdf, *.txt, *.c,etc..

and so on. There are pdf files all over the place, but I only want to delete all the pdf files which are in folders called rules/ and no other place.

I think I need to use

  cd source
  find  / -type d -name "rules"  -print0 | xargs -0 <<<rm *.pdf?? now what?>>>

But I am not sure what to do after getting list of all subfolders named rules/

Any help is appreciated.

On Linux mint.


4 Answers 4


I would execute a find inside another find. For example, I would execute this command line in order to list the files that would be removed:

$ find /path/to/source -type d -name 'rules' -exec find '{}' -mindepth 1 -maxdepth 1 -type f -iname '*.pdf' -print ';'

Then, after checking the list, I would execute:

$ find /path/to/source -type d -name 'rules' -exec find '{}' -mindepth 1 -maxdepth 1 -type f -iname '*.pdf' -print -delete ';'

With a shell that supports extended globs and null globs e.g. zsh:

for d in ./**/rules/
set -- ${d}*.pdf(N)                               
(( $# > 0 )) && printf %s\\n $@

or bash:

shopt -s globstar
shopt -s nullglob
for d in ./**/rules/
set -- "${d}"*.pdf
(( $# > 0 )) && printf %s\\n "$@"

replace printf %s\\n with rm if you're happy with the result.

Since you are on gnu/linux you could also run:

find . -type f -regextype posix-basic -regex '.*/rules/[^/]*.pdf' -delete

remove -delete if you want to perform a dry-run.


Easiest would be

find source -name '*.pdf' -path '*/rules/*.pdf' -exec rm '{}' +

Why the first -name? Because it'll be a bit faster this way. Also + instead of ; executes one rm with many arguments instead of many with one argument. So less process spawning. In bash you can get away without quoting {}.

  • Yes, I had this in mind but I avoided using it due to the initial requirements. Question was edited and this works now because "the rules/ subfolders have no other subfolders." otherwise with subdirs, a file like ./somedir/rules/noway/somefile.pdf would be deleted even if it's not in rules but in one of its children so in that case prolly something like find . -path '*/rules/*/*' -prune -o -path '*/rules/*.pdf' -delete Anyway, you get my vote. As to in bash you can get away without quoting {} - only a couple of shells need that Mar 16, 2016 at 18:57
  • Why -exec rm with all the parsing pitfalls and race conditions waiting to happen instead of -delete?
    – Caleb
    Mar 16, 2016 at 19:55
  • @Caleb - would you mind elaborating a bit on the first part ? What "parsing pitfalls" are we talking about when using find with -exec rm {} ? Mar 16, 2016 at 21:22

You can use a bash script to do it (not the best way):


# Don't screw us up with spaces!
IFS=$'\n'; set -f

DIRS=$(find . -type d -name "rules")

for i in $DIRS; do
  set +f
  rm $i/*.pdf
set +f

This iterates through the directories you find in your find command and removes the pdf's under each directory.

The line IFS=$'\n' is to cope with spaces in file names, and set -f is to cope with wildcard characters. Of course, this is assuming you don't have newlines in any of your filenames. If you do, the solution will become a lot more complicated.

  • 3
    What if any of those dirs has funky chars in its name (path) ? (hint: IFS) Mar 15, 2016 at 23:57
  • @don_crissti The script would fail. Don't put funky chars in your filenames, children! Although, any whitespace would also fail the script. That's a good point.
    – dma1324
    Mar 16, 2016 at 0:01
  • 2
    That's still pretty bad. Avoid the for f in $(find...) construct. find is a robust tool and you can do this find-only in a reliable manner. Mar 16, 2016 at 0:15
  • Better than fiddling with IFS, you should just avoid the split+glob operator. There are robust ways to do it, why insist on fragile ways? Mar 16, 2016 at 0:25
  • It's just one way to do it. There are other ways that I haven't done before. In fact, this is the way I would have done it before I learned about these things in find.
    – dma1324
    Mar 16, 2016 at 0:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.