Remove only files in directory on linux NOT directories [closed]
Asked Answered
L

10

104

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?

Laminar answered 10/10, 2011 at 15:13 Comment(0)
L
-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.

Laminar answered 20/7, 2013 at 21:0 Comment(0)
L
107
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.

Landing answered 5/8, 2012 at 23:56 Comment(3)
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.Handclasp
on some versions this throws a warning, better turn the arguments around like: find /path/to/file -maxdepth 1 -type fChristlike
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.Kookaburra
O
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.

Owlet answered 10/10, 2011 at 15:16 Comment(4)
It's worth mentioning that this will also remove files from all sub-directories, not only the current directory.Thunell
@staven This won't work then, want only the files directly under the specified directory to be deleted..Laminar
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;doneCortege
@Thunell No it won't remove files from subdirectories because of the -maxdepth 1.Flamsteed
U
30

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.

Unstrap answered 23/3, 2013 at 12:52 Comment(4)
The problem is that this creates standard error, which we don't want in shell scripts.Jericajericho
@Jericajericho 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).Unstrap
How to delete the hidden files as well? For example, a file called .htaccess is not removed. Ahh, this answer has helped me.Longeron
Be careful as the * operator does NOT work if you quote the path like in rm -f "tmp/*".Mann
H
11

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 *
Hairstreak answered 8/9, 2016 at 9:13 Comment(1)
If you don't want to see the error stating that it can't remove the directory, execute rm * 2> /dev/nullBernie
S
8

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.

Selima answered 27/1, 2012 at 18:15 Comment(2)
Thanks, brother. I think this is the easiest solution. Upvote.Saltigrade
I prefer this answer. It deletes all files in a directory without deleting subdirectories.Disservice
C
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.

Chambermaid answered 9/3, 2017 at 23:31 Comment(0)
E
4

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

Eyeopening answered 10/10, 2011 at 16:57 Comment(8)
rm -f * doesn't delete directories without -r. It just ignores empty directories and doesn't ask for confirmation. rm -rf * deletes also directories.Unstrap
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.Rajasthani
@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.Eyeopening
@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.Rajasthani
@Unstrap 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.Handclasp
@Handclasp 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...Unstrap
@Unstrap 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".Eyeopening
-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.Nailbrush
K
2

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

Kleper answered 22/12, 2014 at 21:19 Comment(0)
L
0

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

Luting answered 14/11, 2021 at 6:32 Comment(2)
This command also deletes files in sub-directories.Knap
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.Luting
L
-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.

Laminar answered 20/7, 2013 at 21:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.