I'm trying to delete a ton of files older than x days.

Now I have a script to do that

find /path/to/files* -mtime +10 -exec rm {} \; 

But this will also delete the subdirectories. There are a ton of folders but I would like to keep them, and delete the files older than 10 days within the said folders.

Is there a way to do this?


type option for filtering results

find accepts the type option for selecting, for example, only files.

find /path/to/files -type f -mtime +10 -delete

Leave out -delete to show what it'd delete, and once you've verified that, go ahead and run the full command.

That would only run on files, not directories. Use -type d for the inverse, only listing directories that match your arguments.

Additional options

You might want to read man find, as there are some more options you could need in the future. For example, -maxdepth would allow you to only restrict the found items to a specific depth, e.g. -maxdepth 0 would not recurse into subdirectories.

Some remarks

  • I wonder how the command would have removed a folder, since you can't remove a folder with rm only. You'd need rm -r for that.

  • Also, /path/to/files* is confusing. Did you mean /path/to/files/ or are you expecting the wildcard to expand to several file and folder names?

  • Put the {} in single quotes, i.e. '{}' to avoid the substituted file/directory name to be interpreted by the shell, just like we protect the semicolon with a backslash.

| improve this answer | |
  • Well there are a lot of folders within /path/to/files/ actually I would like to run the mtime +10 -exec rm to each of those folders but keep the folders itself, basically I would like to achieve is that delete all the files older than 10days and keep all the folders. I'm a newb sorry bout that newbness :) – JoyIan Yee-Hernandez Jan 5 '12 at 16:26
  • Well, there you go :) Just do a find /path/to/files* -type f -mtime +10 and see what it would output. – slhck Jan 5 '12 at 16:28
  • Yup, when in doubt, don't do the -exec, just see what it finds first. – Rob Jan 5 '12 at 17:19
  • 2
    @JoyIanYee-Hernandez You can also use the -delete argument to find, which deletes all files and folders, the latter only if empty. It implies -depth, i.e. depth-first search. – Daniel Beck Jan 5 '12 at 17:40
  • 1
    @Kreker Then you need to add -mindepth 1 to exclude the parent directory. – slhck Jun 5 '15 at 12:22

As in previous answers (+1 for both) the trick is to use -type f predicate.

Note, that instead of -exec rm '{}' you can also use -delete predicate. But don't do that. With -exec rm '{}' you can (and should) first do -exec echo rm '{}' to verify that this is really what do you want. After that rerun the command without the echo.

Using -delete is faster (no extra fork() and execve() for each file), but this is risky because -delete works also as a condition, so:

# delete *.tmp files
find . -type f -name '*.tmp' -delete

but if you ONLY swap arguments:

# delete ALL files
find . -type f -name '*.tmp' -delete

If you ever need find and rm to work faster for tons of files, check out the find ... | xargs ... rm UNIX idiom.

| improve this answer | |
  • 4
    I think your last two examples are exactly the same, might want to correct that! – slhck May 23 '12 at 18:11

You can easily do this with the find command

$ find -type f

Which restricts the results to be of the type file

| improve this answer | |

I was struggling to get this right using the scripts provided above and some other scripts especially when files and folder names had newline or spaces.

Finally stumbled on tmpreaper and it has been worked pretty well for us so far.

tmpreaper -t 5d ~/Downloads

tmpreaper  --protect '*.c' -t 5h ~/my_prg

Original Source link

Has features like test, which checks the directories recursively and lists them. Ability to delete symlinks, files or directories and also the protection mode for a certain pattern while deleting

| improve this answer | |

To speed up the command use '+' instead of \;

find /path/to/files* -type f -mtime +10 -exec rm '{}' '+'

This will run rm only once at the end instead of each time a file is found.
(rm may be run several times if your have really tons of files because of the command line length limitation, but this is still almost as fast as using -delete)

| improve this answer | |

rm -f find /path/to/files -type file -mtime -5

This will delete the files that are modified within 5 days

rm -f find /path/to/files -type file -mtime +5

This will delete the files that are modifed prior 5 days

Use ` before find and at the end after 5.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.