I have a directory called outer
.
outer
contains a directory named inner
(which contains lots of files of same extension)
I cd
to outer
. How can I delete all the files within inner
but leave the directory inner
remaining (but empty)?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityIf you want to delete a directory's contents and not the directory itself, all you need to do is tell rm
to delete the contents:
rm inner/*
That will delete all non-hidden files in ./inner
and leave the directory intact. To also delete any subdirectories, use -r
:
rm -r inner/*
If you also want to delete hidden files, you can do (assuming you are using bash):
shopt -s dotglob
rm -r inner/*
That last command will delete all files and all directories in inner
, but will leave inner
itself intact.
Finally, note that you don't need to cd
to outer
to run any of these:
$ tree -a outer/
outer/
├── dir
└── inner
├── dir
├── file
└── .hidden
3 directories, 2 files
I can now run rm -r outer/inner/*
from my current directory, no need to cd outer
, and it will remove everything except the directory itself:
$ shopt -s dotglob
$ rm -r outer/inner/*
$ tree -a outer/
outer/
├── dir
└── inner
2 directories, 0 files
find inner -mindepth 1 -delete
find
.
Aug 2, 2022 at 17:00
rm
with glob it removes dot files too, it doesn't fail with "Argument list too long" on big list of files.
If you want to delete all files under some directory structure, but keep all directories, the easiest is to use find
's -delete
switch:
find /path/to/outer -type f -delete
To first check what would be deleted, just leave out the -delete
at the end.
find inner ! -path inner -delete
This would traverse the inner
directory and delete everything. The ! -path inner
test makes sure that the inner
directory itself is not deleted (but all its contents is deleted).
The above would work on Linux with GNU find
(the default find
). The -delete
action is however non-standard (albeit commonly implemented). For a standard compliant variation, use
find inner -depth ! -path inner -exec rm -r {} +
The -depth
option makes sure that find
does a depth-first traversal of the directory structure. Without this, you may end up trying to delete directories before they are empty.
-path
is not documented for AIX's (primitive) find
command, but appears to work anyway. You could also cd to inner and then use find . -depth ! -name . -exec rm -r {} +
I use this loop alot, this way you can apply to any number of folders, don't even need to wory!
for i in `ls`; do rm -f $i/*; done
How about this?
cd inner
ls -A | xargs -I {} rm -r "{}"
Edit: DO NOT USE. This has security issues if the filename contains quotes or newlines. (Code injections for example)
-
would also be a problem, however, I don't think it could delete files outside the top directory. xargs
may end up passing ..
as one argument to rm
, however rm
implementations are meant to reject those.
May 4, 2022 at 11:41
ls -A | xargs -I {} rm -r "{}"
?
May 6, 2022 at 10:33
touch '"hello world"'
(filename containing quotes), and touch $'hello\nworld'
(filename containing newline).