101

What delete command can be run to remove only files in given directory

  • NOT directories
  • NOT sub-directories
  • NOT files in these sub-directories.

Some files don't have extensions so rm *.* wont work...

There are thousands of files in this folder.

Any advice?

Simson
  • 3,373
  • 2
  • 24
  • 38
AndrewC
  • 1,282
  • 2
  • 11
  • 10

10 Answers10

101
find PATH -maxdepth 1 -type f -delete

BUT this won't prompt you for confirmation or output what it just deleted. Therefore best to run it without the -delete action first and check that they're the correct files.

assylias
  • 321,522
  • 82
  • 660
  • 783
James
  • 1,122
  • 1
  • 8
  • 8
  • 5
    This is my favorite solution, since it is one command; the fact that it doesn't invoke -exec is also a plus for me, since that requires knowledge of two distinct commands unnecessarily. IMO this should be the accepted answer. – InfernalRapture Jan 02 '15 at 16:22
  • 6
    on some versions this throws a warning, better turn the arguments around like: find /path/to/file -maxdepth 1 -type f – Max Oct 23 '17 at 13:36
  • In 2020, I _findally_ learned there is a `-delete` parameter -- much simpler than `-1` and a following xargs. Works on [this version of] OS X as well, as `find` is annoyingly different between some *IX distributions. – user2864740 Jun 15 '20 at 23:03
73

You can use find with -type f for files only and -maxdepth 1 so find won't search for files in sub-directories of /path/to/directory. rm -i will prompt you on each delete so you can confirm or deny the delete. If you dont care about being asked for confirmation of each delete, change it to rm -fv (-f for force the delete). The -v flag makes it so that with each delete, a message is printed saying what file was just deleted.

find /path/to/directory -maxdepth 1 -type f -exec rm -iv {} \;

This should meet the criteria:

NOT directories
NOT subdirectories
NOT files in these subdirectories.

Andreas
  • 9,245
  • 9
  • 49
  • 97
chown
  • 51,908
  • 16
  • 134
  • 170
  • 2
    It's worth mentioning that this will also remove files from all sub-directories, not only the current directory. – Staven Oct 10 '11 at 15:24
  • 1
    @staven This won't work then, want only the files directly under the specified directory to be deleted.. – AndrewC Oct 10 '11 at 15:31
  • 1
    I can never make exec do what I want, so I make the loop explicit: `for r in $(find /path/to/directory -type f -maxdepth 1);do rm -v $r;done` – Robert Calhoun Mar 17 '13 at 01:59
  • 2
    @Staven No it won't remove files from subdirectories because of the -maxdepth 1. – kovacsbv May 19 '20 at 15:44
28

Since this is high on google search, the simplest answer is:

rm $directoryPath/*

where $directoryPath is the directory you want to empty. Credits should go to cbm3384 (that for some reason has gotten negative votes for this answer, why?)

If you do not want to confirm:

rm -f $directoryPath/*

If you don't believe try man rm or

mkdir -p 1/2/3; echo 'hello1' > 1/hello1.txt; echo 'hello2' > 1/2/hello2.txt;echo 'hello3' > 1/2/3/hello3.txt
rm 1/2/*

The above creates a directory structure, that has 'helloX.txt' in each folder (X is the directory level). rm 1/2/* deletes hello2.txt and leaves the other structure intact.

Also rm */*/* deletes only hello2.txt. It is the only that matches the pattern.

Just an example of a Makefile that cleans cakephp tmp-directory and leaves the directory structure intact:

clean:
    -rm -f tmp/*
    -rm -f tmp/*/*
    -rm -f tmp/*/*/*
    -rm -f tmp/*/*/*/*

Minus in front of the rm means "do not halt on errors" (unremoved directory returns an error). If you want some level to be saved, just remove that line, e.g. second rm line removes logs.

Let me know if you have a system that does something else (BSD?).

EDIT: I tested this on ubuntu 12.04, osx lion and sourceforge.net shell. All behave like the explanation above.

Juha
  • 2,053
  • 23
  • 44
  • 2
    The problem is that this creates standard error, which we don't want in shell scripts. – zachaysan Aug 31 '15 at 22:18
  • @zachaysan True, if you want silent, redirect stderr to somewhere else: `rm -r $path/* 2> /dev/null` In anycase you are right, this raises errors and suppressing *all* errors is generally bad programming. Same applies if you modify the exit status to 0 (success). – Juha Sep 11 '15 at 23:17
  • How to delete the hidden files as well? For example, a file called `.htaccess` is not removed. Ahh, [this answer](https://askubuntu.com/a/60433/783280) has helped me. – Pathros Apr 20 '20 at 18:47
  • Be careful as the `*` operator does NOT work if you quote the path like in `rm -f "tmp/*"`. – FireEmerald Mar 06 '23 at 14:50
10

rm won't delete directories by default. So in your example, assuming you're in the parent directory and those are all the files, all you need is:

rm *
Andriyun
  • 506
  • 6
  • 9
  • 3
    If you don't want to see the error stating that it can't remove the directory, execute `rm * 2> /dev/null` – SALEH Aug 07 '19 at 21:52
7

TL;DR:

find . -maxdepth 1 -type f -delete

Etc:

Not a big deal but the suggestions above didn't work for me because...

find . -type f -maxdepth 1 -delete

find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.

Geoffrey Hale
  • 10,597
  • 5
  • 44
  • 45
7

rm -f dirname/* will remove only files without prompting for each file. It will also display "Cannnot remove 'subdirname': Is a directory" for each sub directory.

Anuga
  • 2,619
  • 1
  • 18
  • 27
cbm3384
  • 281
  • 1
  • 6
  • 14
4

rm dirname/*? Without -f it won't force-delete, without -r it won't recurse and delete directories as well as files.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • `rm -f *` doesn't delete directories without `-r`. It just ignores empty directories and doesn't ask for confirmation. `rm -rf *` deletes also directories. – Juha Mar 23 '13 at 11:58
  • I ran `rm -r dirname/` and it *did* delete both the top-level directory and all subdirectories and files without any prompting. I tried `rm -r dirname/*` (with the asterisk) and that deleted all subdirectories and files but left the top-level directory. Conclusion: `rm` without `-f` **will** delete directories if you specify `-r`. – Mark Berry Feb 25 '14 at 16:33
  • @MarkBerry May be shell and/or OS dependent, it didn't for me a couple of years ago, and I didn't have any default RM flags set. – Dave Newton Feb 25 '14 at 16:39
  • @DaveNewton, if you're able, it would be interesting to know if you still get the same results. At the least, people need to know it may not be universal and they should test first. – Mark Berry Feb 26 '14 at 03:23
  • @Juha This is most definitely dependent on your default shell configuration. "User friendly" flavors of Gnu+Linux may have 'rm -ri' as the default 'rm' alias which is why you see this behavior. Just as many use '/bin/cp -i' as the default 'cp' behavior. – InfernalRapture Jan 02 '15 at 16:21
  • @InfernalRapture Putting -r to rm turns the command into a weapon of mass destruction. IMHO That should not be done ever. Typoing `rm * tmp` instead of `rm *tmp` for example would be a catastrophic in root or close to root directories... – Juha Jan 15 '15 at 16:11
  • 2
    @Juha Which is probably why the default in some systems is to add the `-i` option. I works be unhappy if I was forbidden to use `-r`, I use it quite frequently, without mishap. I'm on the command line most of the time and short of a command that moved files instead of deleting them would be the only acceptable solution. Even that would need to delete them "eventually". – Dave Newton Jan 15 '15 at 16:45
  • -f means "force", try man rm. If you can site a specific version of rm that this is not the case, I'd love to know, else this post looks incorrect - it looks like the poster is confusing "-f" to mean "files only"; or best case the post is unclear and confusing; two things not good to have around a post about "rm", or any possibly irreversible Linux feature for that matter. – Kit10 Jun 22 '16 at 17:55
1

For this, I would use find with a max depth of 1 and then exec rm with the file list.

find ./dir -maxdepth 1 -type f -exec rm -rf '{}' \;

Edit: this is essentially the same as what James posted but I didn't see his post until after

Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
SelfTaught
  • 482
  • 6
  • 16
-1

What worked for me is a PERL script:

perl -e 'chdir "subdirectory_name" or die; opendir D, "."; while ($n = readdir D) { unlink $n }'

Run this one level up from the directory you wish to clean: replace "subdirectory_name" with the directories name.

Worked on millions of files without killing the CPU.

AndrewC
  • 1,282
  • 2
  • 11
  • 10
-1

The following two commands will recursively delete all files and symbolic links in the current directory:

find . -type f -delete
find . -type l -delete

As one command, the following works: find . -type f -delete&&find . -type l -delete

Rublacava
  • 414
  • 1
  • 4
  • 16
  • 1
    This command also deletes files in sub-directories. – bskp Jan 10 '22 at 13:23
  • True, I think I was sorta answering a question that I had, and not the one OP had. Here is a correction for OP which deletes all files and symlinks in the current directory only: `find . -maxdepth 1 -type f -delete; find . -maxdepth 1 -type l -delete`. – Rublacava Jan 12 '22 at 06:27