6

I want to find all directories that contain a certain file and then delete those directories. With

find . -name thatcertainfile -execdir pwd \;

I get a list of all the directories I want to delete, but how could I delete all those directories on the fly? Note, that I want to delete the whole directory and not just the file itself, where I could use

find . -name thatcertainfile -exec rm -r {} \;

3 Answers 3

2

Try this command:

rm -rf $(find . -name thatcertainfile -execdir pwd \;)

It should say to the rm -rf that what it had to remove is the output of your command. For example, if your command's output was /home/guest/Documents the command I showed would translate on rm -rf /home/guest/Documents.

8
  • 2
    That's exactly what I was looking for. Thanks!
    – snurden
    Commented Apr 28, 2016 at 10:37
  • Was about to do that, however, SE seemingly has a time delay on that, which prevents accepting an answer for a few minutes :)
    – snurden
    Commented Apr 28, 2016 at 10:42
  • 2
    This mostly works, but will break on directories containing spaces, tabs, shell glob characters, etc (all of which are valid chars in filenames and dirnames - the only chars that aren't are / and NUL). It would be safer to use find ... | xargs -d '\n' rm -rf, that will work on any directory name except those containing newlines. Unfortunately, I don't think there's any way to use NUL-terminated file/dirnames (which would have been better) when you rely on the output of -exec or -execdir for the list of files/dirs.
    – cas
    Commented Apr 28, 2016 at 15:08
  • 2
    If you create a directory mkdir -p './ /* /thatcertainfile' just before you run this command, you will end up running rm -rf /*. Let's say you're not root; if you create a directory mkdir -p "./ $HOME/ /thatcertainfile" you will end up forcefully removing your entire home directory. I'd recommend you never use the command given in this answer, under any circumstances. (At least use rm -ri instead, which will prompt you for each deletion.)
    – Wildcard
    Commented Apr 29, 2016 at 0:56
  • 1
    BTW, there are some things I'd be willing to risk using the output of $(find ...) with, but rm -rf is NOT one of them. Even if i knew there were no unusual file/dir names being output, the combination of rm -rf and shell-globbing of unknown filenames would make me extremely nervous. Just seeing a command like that would make me think "WTF am i doing? find a better way!"
    – cas
    Commented Apr 29, 2016 at 1:06
2

Given a path to the file ./some/where/thatcertainfile, stripping off the final /thatcertainfile gives you a path to the directory. Launch a shell to be able to use string manipulation on the path.

find . -name thatcertainfile -exec sh -c 'rm -r "${0%/*}"' {} \;

Alternatively, use zsh. To transform a path into the name of the containing directory, use the :h history modifier via a glob qualifier.

rm -rf **/thatcertainfile(N:h)

(Obviously, test this first before running it with rm!)

0

This pipeline should do the job and be safe from directories with spaces in their names.

find . -name thatcertainfile -print0 | xargs --null dirname -z | xargs --null rm -r

If anyone sees a problem with this I would like to know.

2
  • Support for find -print0 and xargs --null required, e.g. a GNU-based environment. Those aren't POSIX.
    – phk
    Commented Jan 26, 2017 at 15:40
  • If no files are found, you get an error from dirname.
    – Justsalt
    Commented Jan 26, 2017 at 15:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .