How do I delete all but 10 newest files in Linux?

For a portable and reliable solution, try this:

ls -1tr | head -n -10 | xargs -d '\n' rm -f --

The tail -n -10 syntax in one of the other answers doesn't seem to work everywhere (i.e., not on my RHEL5 systems).

And using $() or `` on the command line of rm runs the risk of

  1. splitting file names with whitespace, and
  2. exceeding the maximum commandline character limit.

xargs fixes both of these problems because it'll automatically figure out how many args it can pass within the character limit, and with the -d '\n' it will only split at the line boundary of the input. Technically this can still cause problems for filenames with a newline in them, but that's far less common than filenames with spaces, and the only way around the newlines would be a lot more complicated, probably involving at least awk, if not perl.

If you don't have xargs (old AIX systems, maybe?) you could make it a loop:

ls -1tr | head -n -10 | while IFS= read -r f; do
  rm -f "$f"
done

This will be a bit slower because it spawns a separate rm for each file, but will still avoid caveats 1 and 2 above (but still suffers from newlines in file names).


The code you'd want to include in your script is

 rm -f $(ls -1t /path/to/your/logs/ | tail -n +11)

The -1 (numeric one) option prints each file on a single line, to be safe. The -f option to rm tells it to ignore non-existent files for when ls returns nothing.


Apparently parsing ls is evil.

If each file is created daily and you want to keep files created within the last 10 days you can do:

find /path/to/files -mtime 10 -delete

Or if each file is created arbitrarily:

find /path/to/files -maxdepth 1 -type f -printf '%Ts\t%P\n' | sort -n | head -n -10 | cut -f 2- | xargs rm -rf

A tool like logrotate does this for you. It makes log management much easier. You can also include additional cleanup routines shuch as halo sugggested.