4

I have a compressed (tar), backup file which is added to a directory periodically. The files that are added have a naming convention like so:

JenkinsBackup_$(date +%Y%m%d-%H%M%S).tar.gz

Which results in files named like:

jenkinsBackup_20170630-091543.tar.gz

My goal is to select all files within the directory older than the most recent ten files added to the directory, and delete those files. Essentially a cleanup of the directory from command line.

Can anybody help me with the terminal commands needed to accomplish this? I'm not sure how to select and remove all files within a directory older than the most recent ten files.

Thanks in advance for any help!

1
  • logrotate may already do what you want – ti7 Jun 30 '17 at 21:24
6

A simple way that works fine with your file names is to use:

ls -t1 | tail -n +11 | xargs gvfs-rm
  • ls -t1 gives us a list of files based on their modification time, and newest files are first.
  • using tail -n +11 we are skipping first 10 line and getting everything else
  • then we pipe the list to xargs gvfs-rm for removal.

Note that gvfs-rm moves the file to the trash, use rm to permanently remove them.

If you want to work with the file names instead of their modification time then use ls -1r | tail -n +11 | xargs gvfs-rm instead.

A similar find solution that decides based on file names:

find -type f | sort -r | tail -n +11 | xargs gvfs-rm

or

find -type f | sort | head -n -10 | xargs gvfs-rm
6
  • It looks like this may keep the oldest ten, and removing anything newer than the oldest ten files. I am trying to keep the newest ten, and remove anything older than the ten newest files. Thank for for the advice though so far very helpful! – J0991 Jun 30 '17 at 13:46
  • Yes i tested the command listed above in terminal and I see my most recent file (the 11th), removed from the directory. In this case, the 1st file of the 11 should be removed. – J0991 Jun 30 '17 at 13:49
  • 1
    It worked perfectly! Thanks you saved my ass this morning :D Just wondering if you have the time to update the description of the command executed in your answer above? I'd like to know exactly why this works! – J0991 Jun 30 '17 at 13:55
  • 1
    Updated again and you're welcome... – Ravexina Jun 30 '17 at 13:59
  • 1
    Your the best! Thank you very much for your effort! – J0991 Jun 30 '17 at 13:59
2

Python

I assume the directory contains only your backups. If it has other files, the wrong files will get deleted.

import os
for f in sorted(os.listdir('.'))[:-10]:
    os.remove(f)

Explanation

  • os.listdir('.') gets filenames in the current directory
  • sorted() sorts the filenames in ascending order (oldest first)
  • [:-10] selects the whole list except the last ten items
  • os.remove() deletes each file
1

If you have access to zsh it's much easier than jumping though hoops with ls, find or stat. For example, given

 % ls -1 JenkinsBackup_*
JenkinsBackup_20170630-095544.tar.gz
JenkinsBackup_20170630-095545.tar.gz
JenkinsBackup_20170630-095546.tar.gz
JenkinsBackup_20170630-095547.tar.gz
JenkinsBackup_20170630-095548.tar.gz
JenkinsBackup_20170630-095549.tar.gz
JenkinsBackup_20170630-095550.tar.gz
JenkinsBackup_20170630-095551.tar.gz
JenkinsBackup_20170630-095552.tar.gz
JenkinsBackup_20170630-095553.tar.gz
JenkinsBackup_20170630-095554.tar.gz
JenkinsBackup_20170630-095555.tar.gz
JenkinsBackup_20170630-095556.tar.gz
JenkinsBackup_20170630-095557.tar.gz
JenkinsBackup_20170630-095558.tar.gz

List by modification time, newest first using the om (order by modification time) glob qualifier:

 % printf '%s\n' JenkinsBackup_*(om)
JenkinsBackup_20170630-095558.tar.gz
JenkinsBackup_20170630-095557.tar.gz
JenkinsBackup_20170630-095556.tar.gz
JenkinsBackup_20170630-095555.tar.gz
JenkinsBackup_20170630-095554.tar.gz
JenkinsBackup_20170630-095553.tar.gz
JenkinsBackup_20170630-095552.tar.gz
JenkinsBackup_20170630-095551.tar.gz
JenkinsBackup_20170630-095550.tar.gz
JenkinsBackup_20170630-095549.tar.gz
JenkinsBackup_20170630-095548.tar.gz
JenkinsBackup_20170630-095547.tar.gz
JenkinsBackup_20170630-095546.tar.gz
JenkinsBackup_20170630-095545.tar.gz
JenkinsBackup_20170630-095544.tar.gz

List by modification time, newest first, and select from the 11th up:

 % printf '%s\n' JenkinsBackup_*(om[11,-1])
JenkinsBackup_20170630-095548.tar.gz
JenkinsBackup_20170630-095547.tar.gz
JenkinsBackup_20170630-095546.tar.gz
JenkinsBackup_20170630-095545.tar.gz
JenkinsBackup_20170630-095544.tar.gz

Delete matching files older than the 10th newest:

 % rm -v JenkinsBackup_*(om[11,-1])
removed 'JenkinsBackup_20170630-095548.tar.gz'
removed 'JenkinsBackup_20170630-095547.tar.gz'
removed 'JenkinsBackup_20170630-095546.tar.gz'
removed 'JenkinsBackup_20170630-095545.tar.gz'
removed 'JenkinsBackup_20170630-095544.tar.gz'

See zsh: 14 Expansion: Filename Generation

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.