13

What command do I have to use to delete all directories that begin with graphene-80 under the directory /tmp?

What can I add to the rm command as option?

Kusalananda
  • 333,661
Thouraya
  • 139

4 Answers4

18

To delete the directories matching the pattern graphene-80* directly under /tmp, use

rm -rf /tmp/graphene-80*/

Here, the trailing / ensures that only directories whose names match the graphene-80* pattern are deleted (or symbolic links to directories), and not files etc.

To find the matching directories elsewhere under /tmp and delete them wherever they may be, use

find /tmp -type d -name 'graphene-80*' -prune -exec rm -rf {} +

To additionally see the names of the directories as they are deleted, insert -print before -exec.

The two tests -type d and -name 'graphene-80*' tests for directories with the names that we're looking for. The -prune removes the found directory from the search path (we don't want to look inside these directories as they are being deleted), and the -exec, finally, does the actual removal by means of calling rm.


Addressing question in comments: "How would you delete all files within that directory (not the directory itself)?"

One of the below:

  • Recreate the directories after deleting them:

    find /tmp -type d -name 'graphene-80*' -prune \
        -exec rm -rf {} \; -exec mkdir {} +
    

    or more efficiently, doing both operations in batches,

    find /tmp -type d -name 'graphene-80*' -prune \
        -exec sh -c 'rm -rf "$@"; mkdir "$@"' sh {} +
    

    The benefit of this is the simplicity of the command (compared to the command below).

  • Use a small in-line shell script to only delete the names (files and directories) within the found directories:

    find /tmp -type d -name 'graphene-80*' -prune -exec bash -O nullglob -O dotglob -c '
        for dirpath do
            rm -rf "$dirpath"/*
        done' bash {} +
    

    This executes a small in-line bash script with batches of found directory pathnames. The shell is started with the nullglob and dotglob shell options set. The nullglob option is used for expanding non-matching shell patterns to nothing rather than leaving them unexpanded, and the dotglob shell option is used for matching hidden names (* does not match hidden names by default). The script iterates over the given directory paths and empties each directory recursively.

    The benefit of doing it this way is that it adequately deals with found directory paths that happen to be mount points. The downside is the complexity of the command and the fact that I had to write all this text to describe what it's doing (which means it will potentially be difficult for the next person to take over maintenance of the script).

Kusalananda
  • 333,661
  • How would you delete all files within that directory (not the directory itself)? Thanks! – Emmanuel Goldstein Feb 20 '23 at 05:48
  • @EmmanuelGoldstein See added bit at the end of the answer. – Kusalananda Feb 20 '23 at 06:51
  • Thanks, however, I don't understand unix commands and when you say "Recreate the directories after deleting them" I guess you are deleting the directories themselves? I only want to find /path/to/dir/FOO1234 and delete its contents for all FOO* directories. – Emmanuel Goldstein Feb 20 '23 at 07:42
  • @EmmanuelGoldstein Deleting the directory (and all contents) and then creating the directory again will leave you with a newly created, empty, directory. In effect, the directory at that path has been emptied, which is what you wanted, right? – Kusalananda Feb 20 '23 at 07:44
  • Yes, I will try then. I thought there was no need to delete directory, but if that is the way to go, then so be it. – Emmanuel Goldstein Feb 20 '23 at 08:37
  • It works! Is the "" necessary or is it to indicate new line? I want to use it as a cron command, can I just write ´´´find "/Users/user/Library/Group Containers" -type d -name 'account-*' -prune -exec rm -rf {} ; -exec mkdir {} +´´´ ? – Emmanuel Goldstein Feb 20 '23 at 08:44
  • 1
    @EmmanuelGoldstein The backslash at the end of the line is only used for line-continuation. If you write everything on a single line, then delete it. – Kusalananda Feb 20 '23 at 08:45
  • Thanks, and lastly, if I want to target a specific folder within "account", I have tried doing this but it won't work: ```'account-/postbox/media'Because that is the only subfolder I want to target withinaccount-*```. – Emmanuel Goldstein Feb 20 '23 at 08:52
  • 1
    @EmmanuelGoldstein Instead of a -name test, use a -path test: -path '*/account-*/postbox/media' -type d (etc.) – Kusalananda Feb 20 '23 at 08:54
  • You are the boss! Thank you! – Emmanuel Goldstein Feb 20 '23 at 10:51
6

Using find command:

find /tmp -type d -name 'graphene-80*' -delete

Arguments used:

  • -type to filter directory only and avoid finding files
  • -name to find file that match the pattern define between quotes
  • -delete to delete the result of the find command

EDIT: cleaner with -delete like shown in this post: Find files matching template and remove

0

To remove just empty directories with names matching graphene-80*, either

find /tmp -type d -name "graphene-80*" -exec rmdir {} +

or

find /tmp -type d -name "graphene-80*" -delete

(rmdir and GNU find should give you errors for the nonempty ones.)

To remove the directories with their contents:

find /tmp -type d -name "graphene-80*" -exec rm -r {} \; -prune

(With -exec rm + you may get errors from rm if there are nested matching directories; and without -prune, from find since it tries to descend to the just-removed directories.)

ilkkachu
  • 138,973
-4

You can use the following command: UPDATED

find /tmp -type d -name 'graphene-80*' -prune -exec rm -rf {} +
Hasan Sh
  • 97
  • 2