23

I would like to delete every file, but keep the folder structure. Is there a way?

NOTE: (I'm using GNU bash 4.1.5).

slm
  • 369,824
The Student
  • 3,529

4 Answers4

32

Try this:

find . ! -type d -exec rm '{}' \;

This will delete every single file, excluding directories, below the current working directory. Be extremely careful with this command.

If the version of find on your machine supports it, you can also use

find . ! -type d -delete
  • @slm: I'm not sure how portable that is. I've added it in as a secondary option. I just realized that my edit made my answer virtually identical to yours. Sorry about that; it was not my intent. –  Jul 24 '13 at 20:20
  • Does the '{}' guard against spaces in files? I see you using all the time and I don't think I'd ever seen it used before I saw you posting solutions with it. – slm Jul 24 '13 at 20:21
  • From the GNU find manpage: "Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation." I'm not sure when it's necessary though. I mostly do it out of habit. The find command never sees the quotation marks. It just sees the {} marker as an argument. –  Jul 24 '13 at 20:22
  • I see it on the example, but the templates show this, "-exec command {} +" & this "-exec command ;". I've use the \; in the past just never the '{}'. – slm Jul 24 '13 at 20:26
  • @slm: The templates also don't show the escaping of the semicolon, which is generally necessary when using a shell to execute find. I think the templates are meant to show which arguments the find command needs and don't worry about anything shell-related. –  Jul 24 '13 at 20:28
  • @slm: You could. \{\} is the same as '{}'. –  Jul 24 '13 at 20:35
  • Found this U&L Q&A: http://unix.stackexchange.com/questions/8647/gnu-find-and-masking-the-for-some-shells-which. Doesn't appear that the '{}' is really necessary anymore. – slm Jul 25 '13 at 00:03
  • @slm: Thanks. I'll keep that in mind for the next time I post a solution that uses find -exec. –  Jul 25 '13 at 00:32
  • Just asking b/c I'm trying to learn myself, why did you use ! -type d vs. -type f? – slm Jul 25 '13 at 00:37
  • @slm: -type f only matches regular files. It doesn't match special files such as symlinks and named-pipes. –  Jul 25 '13 at 00:55
  • Great tip. I wanted to empty my directory tree. It has some symbolic links pointing to other directories. To keep directories and links to directories ... Use: find . ! -xtype d -delete. Keeps symbolic links to things of type d (directory). – will Jan 17 '18 at 12:09
  • Great tip. I wanted to empty my directory tree. It has some symbolic links pointing to other directories. To keep directories and links to directories ... Use: find . ! -xtype d -delete. Keeps symbolic links to things of type d (directory). – will Jan 17 '18 at 12:10
9

You can use the command find to locate every file but maintain the directory structure:

$ find /some/dir -type f -exec rm {} +

Per this Unix & Linux Q&A titled: gnu find and masking the {} for some shells - which?, escaping the {} with single ticks (') doesn't appear to be necessary anymore with modern day shells such as Bash.

slm
  • 369,824
1

The easy way to delete every regular file in the current directory and subdirectories recursively:

zsh -c 'rm **/*(.)'

Only zsh has globbing qualifiers to match files by type. However, the rm command doesn't work on directories, so in bash, you can use

shopt -s globstar
rm **/*

This doesn't work for commands other than rm though. In general, you can use find:

find . -type f -delete

or if your find doesn't support -delete:

find . -type f -exec rm {} +
-2

I had similar requirement to delete files from a path and its sub directories (filtering by time ) with out deleting the directory structure .

And i have used the below format which worked for me .

find /test123/home/test_file_hip/data/nfs -mtime +6 -type f -exec rm {} \;

Syntex : find (path of file) -mtime (greater than or less than days) -type f -exec rm {} \;

-type : Mention the type of file "f" for "d" directory -exec : execute command rm : remove {} : output of find command

Note : Do test it before using it . Please feel free to correct or update if i missed anything .

rohit
  • 1
  • 1
    since this is an additional requirement that wasn't mentioned by the OP, and since the basic find ... rm structure has already been covered, I'm not sure this is a valuable contribution as a new Answer to this question. – Jeff Schaller Nov 02 '18 at 14:38