I have searched and searched for an answer to this question, and I have used some of the answers I found in the past for finding and deleting large numbers of directories that are named by a certain pattern, such as all directories named "example" including all of their contents recursively such as /directory1/example/files, /directory2/subdirectory/example/files, /directory3/../../subdirectory/example/more/more/files, where everything below the directory named "example" was deleted including the "example" directory itself. To accomplish that, I've used commands such as

find . -name example -type d -exec rm -rf {} +

THE EXCLAMATION POINT PROBLEM In this case however, I have a large number (maybe 300 or so) of directories that were uploaded to my server accidentally that need to be removed. The unwanted directories are all named "!originals". I need to remove all of the directories as well as all of their contents. My problem is in dealing with the exclamation point which is included in the names of all of these directories. For some reason, I am unable to escape the character when using a command such as the example given above. I have tried

find . -name *originals -type d -exec rm -rf {} +
find . -name !originals -type d -exec rm -rf {} +
find . -name \!originals -type d -exec rm -rf {} +
find . -name "\!originals" -type d -exec rm -rf {} +
find . -name '\!originals' -type d -exec rm -rf {} +

I really thought the last one in the list had potential. But on execution there was nothing happening. Just returning to the command prompt with no errors given and no files or directories affected.

If this has been answered somewhere else, I apologize. But I will be surprised, given the amount of searching I did regarding this issue. I have tried everything I can think of to find a solution, prior to posting here. So I hope this is a valid question, for which someone has a workable solution. Thank you in advance to all of you who provide help here.

  • I solved my own problem. So at least I hope I can help someone else avoid the same stupid error. I was using the locate command to determine if there were still directories named !originals on my server. The problem is that I didn't run updatedb after trying the above commands. It turns out that at least one of the above commands (probably the one using '\!originals') worked for me and removed the unwanted directories. But my locate database simply didn't know it yet. – Brad Sep 7 '20 at 8:02
  • Please post that as an actual answer, and not as a comment. – user1686 Sep 7 '20 at 8:08

Escaping rules for ! are slightly weird, as history expansion works at a different stage than all the other shell special characters. Normally though \! and '!' should be the two methods that work.

You can use set +o histexpand to disable history expansion. This will make ! a normal character.

I would recommend building the find command incrementally – that way it will be easier to narrow down the problem:

  1. Use echo to figure out the escaping rules (as all commands are equally affected by them):

    echo find -name !originals
    echo find -name \!originals
    echo find -name '!originals'
  2. Test a bare minimum search that only compares the name, then prints out results:

    find . -name '!originals'
    (or) find . -name '!originals' -ls
  3. Then extend the check to only consider directories, but still have it print out results instead of doing anything with them:

    find . -name '!originals' -type d
    (or) find . -name '!originals' -type d -print
    (or) find . -name '!originals' -type d -ls
  4. Once the results look right, actually do the removal – at this point, you know that the find conditions are correct and the rest falls on rm:

    find . -name '!originals' -type d -exec rm -rvf {} +

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.