5

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 {} \;

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.

  • 2
    That's exactly what I was looking for. Thanks! – snurden Apr 28 '16 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 Apr 28 '16 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 Apr 28 '16 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 Apr 29 '16 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 Apr 29 '16 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.

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

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.