451

The closest I've gotten is

# rm /path/to/directory/*.*

but that doesn't work for files that don't have an extension...

αғsнιη
  • 35,660
user784637
  • 10,955
  • See answer here, this can remove hidden files as well with out any warning and deleting directory itself https://stackoverflow.com/questions/43832107/delete-contents-but-not-directory-in-linux – Developer Oct 18 '19 at 04:54
  • 1
    I don't have enough reputation to add a real answer, but when using the shopt -s dotglob && rm /path/to/directory/* solution in bash, (shopt -s dotglob && rm /path/to/directory/*) (with parentheses) will prevent shopt -s dotglob from leaking beyond this one command. (Parentheses run the contained commands in a subshell.) – David Winiecki Apr 23 '21 at 18:35

9 Answers9

502

Linux does not use extensions. It is up to the creator of the file to decide whether the name should have an extension. Linux looks at the first few bytes to figure out what kind of file it is dealing with.

  • To remove all non-hidden files* in a directory use:

    rm /path/to/directory/*
    

    However, this will show an error for each sub-directory, because in this mode it is only allowed to delete files.

  • To remove all non-hidden files and sub-directories (along with all of their contents) in a directory use:

    rm -r /path/to/directory/*
    

* Hidden files and directories are those whose names start with . (dot) character, e.g.: .hidden-file or .hidden-directory/. Note that, in Bash, if the dotglob option (which is off by default) is set, rm will act on hidden files too, because they will be included when * is expanded by the shell to provide the list of filename arguments.

Zanna
  • 70,465
Rinzwind
  • 299,756
  • 16
    If you also want to delete hidden files run shopt -s dotglob before running rm (...) – danjjl Sep 06 '11 at 08:10
  • Wow that's pretty incredible that you know that off the top of your head. What exactly does the asterisk mean? – user784637 Sep 06 '11 at 08:12
  • 12
    The * means all files ;) *.* means all files containing a . somewhere in the name – Rinzwind Sep 06 '11 at 08:20
  • 12
    @Rinzwind, more accurately, the asterisk means "zero or more of any character". So *a* means zero or more characters, followed by a followed by zero or more characters. It would match the filenames happy, apple, a or la. – DisgruntledGoat Sep 06 '11 at 13:43
  • This doesn't work for files that start with metadata characters. $ rm * rm: invalid option -- '8' – fIwJlxSzApHEZIl Oct 10 '14 at 21:03
  • 1
    Here's the command you want: rm -- * – fIwJlxSzApHEZIl Oct 10 '14 at 21:04
  • 3
    I would've just used rm -r /path/to/directory except that will get rid of the directory itself. At least this way you can get rid of the hidden files too – Kellen Stuart Sep 22 '16 at 18:41
  • 3
    if directory is empty the command returns error: rm: cannot remove 'empty_dir/*': No such file or directory – anton_rh Aug 24 '18 at 11:20
  • In bash, shopt -s dotglob is the a way of matching every file in the directory without accidentally matching . or ..: (shopt -s dotglob; rm -r /path/to/directory/*) – Jarek Przygódzki Sep 24 '18 at 09:39
  • does that mean cd IGNORE /; rm IGNORE -rf * would effectively remove everything from you computer? (I added IGNORE so no one copy/pastes it into their computer, just assume they weren't there) – Honey Mar 31 '20 at 16:23
  • yes. also need sudo ;) – Rinzwind Mar 31 '20 at 16:57
309
  • To remove a folder with all its contents (including all interior folders):

    rm -rf /path/to/directory
    
  • To remove all the contents of the folder (including all interior folders) but not the folder itself:

    rm -rf /path/to/directory/*
    

    or, if you want to make sure that hidden files/directories are also removed:

    rm -rf /path/to/directory/{*,.*}
    
  • To remove all the "files" from inside a folder(not removing interior folders):

    rm -f /path/to/directory/{*,.*}
    

Warning: if you have spaces in your path, make sure to always use quotes.

rm -rf /path/to the/directory/*

is equivalent to 2 separate rm -rf calls:

rm -rf /path/to
rm -rf the/directory/*

To avoid this issue, you can use 'single-quotes'(prevents all expansions, even of shell variables) or "double-quotes"(allows expansion of shell variables, but prevents other expansions):

rm -rf "/path/to the/directory/"*

Where:

  • rm - stands for remove
  • -f - stands for force which is helpful when you don't want to be asked/prompted if you want to remove an archive, for example.
  • -r - stands for recursive which means that you want to go recursively down every folder and remove everything.
Zanna
  • 70,465
  • 16
    I found this to be the more comprehensive and helpful answer, over and above the answer that was marked as Accepted. – inspirednz Aug 20 '16 at 01:58
  • 2
    rm -rf /path/to/directory/* does not remove a hidden file in the folder e.g. .htaccess. Maybe rm -rf /path/to/directory/.? Haven't tried it. – Mark Berry Mar 29 '17 at 01:33
  • @MarkBerry rm -rf /path/to/directory/.* – Lilian A. Moraru Mar 29 '17 at 14:57
  • 1
    @LilianA.Moraru, I did some testing today. rm -rf /path/to/directory/.* only deletes the hidden file(s) in the specified directory. Looking at the @danjjl's comment on @Rinzwind's answer, to also delete hidden files, run shopt -s dotglob before running rm -rf /path/to/directory/*. – Mark Berry Mar 29 '17 at 22:59
  • CAUTION: rm -rf /path/to/directory/.* on my system caused deletion of items in /path/to. Fortunately, I had just backed-up my entire data to a separate disk. Needless to say, do NOT issue the command rm -rf /path/to/directory/.* unless you have backed up your whole computer to a separate / secure location! – lawlist Sep 03 '18 at 18:32
  • @lawlist My guess is that you had a path splitting issues because of spaces in the path. Example: /home/user/Important Stuff/directory. If you do rm -rf /home/user/Important Stuff/directory, it's passing 2 separate arguments to rm -rf, you are actually calling rm -rf /home/user/Important and rm -rf Stuff/directory. Make sure to always use quotes around variables and paths with spaces: rm -rf "/home/user/Important Stuff/directory" or rm -rf '/home/user/Important Stuff/directory'. The issue is not in rm -rf /path/to/directory/.*. – Lilian A. Moraru Dec 21 '18 at 07:48
  • 1
    @lawlist The intention was to keep it short and simple because people don't want to read basically an article but I added the warning about word splitting. Note that this is common and not specific to rm. – Lilian A. Moraru Dec 21 '18 at 08:06
  • 1
    This is not guaranteed to work due to "argument list too long". – Gqqnbig May 30 '21 at 08:36
  • CAUTION: This may cause unexpected behavior, because .* also expands to . and .. aka the current and the parent directory. Try echo .* in an empty dir. The accepted answer shopt -s dotglob; echo * does it correctly, but still fails if the dir is empty, trying to remove a non-existent * file. Hint: I used echo to demonstrate the glob expansion without doing harm to the filesystem. – Holger Böhnke Oct 06 '23 at 16:59
62

To remove all files in directory (including hidden files and subdirectories) run:

rm -rf /path/to/directory/{*,.*}
21

To delete all files and directories(including the hidden ones) in a directory, you can try the following:

  • delete the folder, then recreate it

    rm -rf dir_name && mkdir dir_name
    
  • use find

    find dir_name -mindepth 1 -delete  
    

Here we specify -mindepth 1 to exclude the directory dir_name itself.
Take a look at the following link:
https://unix.stackexchange.com/questions/12593/how-to-remove-all-the-files-in-a-directory

muru
  • 197,895
  • 55
  • 485
  • 740
zeekvfu
  • 421
  • 4
  • 4
13

If you want to delete only files in /path/to/directory you can do

find /path/to/directory -type f -print0| xargs -0 rm 

or

find /path/to/directory -type f -exec rm '{}' \;

You can do loads with find, the advantage is you can list what is found without piping it to rm so you can see what will be deleted before you start.

αғsнιη
  • 35,660
  • 2
    GNU find as a -delete predicate. If you still want to use -exec, substituting \; with + will gather rm calls together, increasing efficiency. – enzotib Sep 06 '11 at 12:19
  • 1
    large amount of files with '+' will cause problems, since list will be too large, same as rm -f *. and when removing large amounts of files from same folder (talking in millons) both of them are not good :) In the end C++ came along and removed files in order of inodes in dir-tree. – Osis Sep 06 '11 at 12:53
  • 3
    You really ought to add a -- after the rm. Without that if you have a file names -rf or similar will be interpreted as arguments to rm. e.g. xargs -0 rm -- or -exec rm -- {} ; – Richm Sep 06 '11 at 13:52
  • you can also provide the -n argument to xargs. That will cause it to split the rm commands to having a maximum number of arguments i.e. 'xargs -n 100 -0 rm --' will remove files in chunks of 100. – Richm Sep 06 '11 at 13:54
  • 1
    You can also add -maxdepth 1 to ensure that find does not return files from any subdirectories. i.e. find /path/to/directory -maxdepth 1 -type f – Richm Sep 06 '11 at 14:10
7

If you also want to remove all subdirectories and the directory itself, you can use rm -rf /path/to/directory. But always double-check your line before pressing return, rm -rf can cause lots of havock as well, e.g. if you accidentally insert a space after the first slash while having superuser permissions...

3

Since this question is constantly at the top of Google when I search for this myself:

The other answers suffer from different problems:

  1. Some of them include . and .. which is noisy, confusing, and annoying.

  2. Some of them forget hidden files (files beginning with a dot).

  3. They don't delete in a correct (deepest-first) order to allow directory deletion.

  4. They descend into other (mounted) file systems, which is often undesired.

  5. They're difficult to extend properly with extra parameters (more on that below).

So, to RECURSIVELY delete all files AND folders in a directory, do this:

find "${DIR}" -xdev -mindepth 1 -printf "%d\t%y\t%p\0" | sort -z -r -n | cut -z -f3- | xargs -0 -r -- rm -d --

Note that I added an -xdev argument to prevent descending into mounts (like /proc etc.).

Why not -depth or -delete?

Despite people constantly downvoting me for this, those methods have a downside: it doesn't seem like they're extensible enough to allow -pruneing a subdirectory (without introducing more problems). By contrast with this method, you could insert

-not \( -path "${DIR}/subdir" -prune \)

before the -mindepth argument to exclude subdir from having its contents deleted.

user541686
  • 4,167
  • And for depth-first order, there's a -depth flag in find for that. – Sergiy Kolodyazhnyy May 21 '18 at 01:36
  • Uh... why not just use -delete with find? -delete is depth-first. You're already assuming non-POSIX find with the -printf, so you might just as well use -delete or -depth -print0 | xargs -0 rm – muru May 21 '18 at 06:41
  • @muru: Because I didn't know better... I'll change it. – user541686 May 21 '18 at 06:47
  • @muru: Actually, it seems your method doesn't work with -not \( -path "$DIR/subdir" \)... but mine does? Why? – user541686 May 21 '18 at 07:00
  • @Mehrdad what is that supposed to do? – muru May 21 '18 at 07:06
  • @muru: Exclude paths under "$DIR/subdir" from being traversed entirely. The problem seems to be that -depth forces traversal, so the files under that path get deleted regardless. – user541686 May 21 '18 at 07:09
  • @Mehrdad of course, because it's also perfectly valid to read that as "delete everything except that which has a path of $DIR/subdir", and that is indeed the behaviour seen. – muru May 21 '18 at 07:11
  • @muru: Well clearly that is useless when you want to preserve a subdirectory... whereas mine actually has an advantage here. I don't understand you guys' eagerness to downvote my honest attempt to provide a better solution here; it's extremely frustrating and discouraging. – user541686 May 21 '18 at 07:14
  • Again, of course, because you're using an ambiguous phrasing. find is preserving the subdirectory: it's not deleted at all. Be precise in what you want find to do, and it will do it. – muru May 21 '18 at 07:18
  • @muru: Thanks for repeating yourself. Again, I already responded to you that I want to let the user be able to preserve a subtree and it's not doing that. Again: I have this solution because it's the best I can think of, i.e. I'm too dumb to think of a better one. How about you tell me your more "precise" method that would let the user do such a thing? – user541686 May 21 '18 at 07:20
  • There are probably better ways to express this, but: https://paste.ubuntu.com/p/7mQ9s8JhJ7/ – muru May 21 '18 at 07:23
2

You can cd into the directory and then run the command rm *.* just like in DOS if you remember.

Eric Carvalho
  • 54,385
V K Mavani
  • 29
  • 1
  • 1
    DOS is DEL for files and RMDIR for emptied directories- and hidden and system files must have those ATTRIB attributes removed first. Not nearly as simple ;) – Eric Jun 10 '15 at 13:03
1

To delete current directory, you could for example use rm -d ./*

-d tells to delete directories as well.

arviman
  • 141