Home > Software design >  Is there any linux command to Keep only 5 recent files that start with REF in a folder?
Is there any linux command to Keep only 5 recent files that start with REF in a folder?

Time:09-16

I would like to make a linux command which will keep only the last 5 recent files, but these files must start with REF, and delete the other files also which start with REF, but not touch the other files. For example: in my folder, I have:

-rw-r--r-- 1 0 Jan 1, 2022 File_0
-rw-r--r-- 1 0 Jan 1, 2022 REF_1
-rw-r--r-- 1 0 Feb 1 2022 REF_2
-rw-r--r-- 1 0 March 1, 2022 REF_3
-rw-r--r-- 1 0 Apr 1, 2022 REF_4
-rw-r--r-- 1 0 May 1, 2022 REF_5
-rw-r--r-- 1 0 June 1, 2022 REF_6
-rw-r--r-- 1 0 Jul 1, 2022 file_7
-rw-r--r-- 1 0 1 Aug 2022 file_8
-rw-r--r-- 1 0 Sep 1, 2022 REF_9

The command should remove only:

-rw-r--r-- 1 0 Jan 1, 2022 REF_1
-rw-r--r-- 1 0 Feb 1 2022 REF_2

... and should keep the other files. I tried ls -t REF* | head -n 4 | xargs rm REF* but this command deletes all files that start with REF!

What command can I use?

CodePudding user response:

Logrotate was mentioned, why not use it?

It can't handlle the separator being an underscore (_).

$ cat log.conf
REF* {
         rotate 5
}
% logrotate log.conf
error: log.conf:1 keyword 'REF' not properly separated, found 0x2a

Here is a complete script, with safe filenames.

find . -name 'REF_*' -print0 | \
    xargs -0 stat -c "%Y %n" | \
    sort -n | \
    head -n 3 | \
    sed -e 's/^[0-9]* //' | \
    tr '\12' '\0' | \
    xargs -0 rm
  1. First, let us use find with nulls to fetch the list of files.
  2. Then use xargs to use stat to prepend the unix time stamp.
  3. Use sort to sort by oldest first.
  4. Use head -n 3 to find all except the last 5.
  5. Use sed to strip the temporary unix time stamp.
  6. Use tr to convert the returns from stat to nulls again.
  7. Finally xargs to delete the unwanted files.

CodePudding user response:

Using zsh (available on many Linux distributions and also on AIX from IBM's AIX Toolbox for Open Source Software), you could simply:

rm -REF*(om[6,-1])

This uses zsh's powerful globbing (filename generation) abilities to:

  • gather the list of files starting with REF
  • sort the files by their modification time (newest first) with (om...)
  • keep the five newest files by selecting the 6th and remaining files with [6,-1]
  • pass that list of files to rm

Test it first with a simple print -l REF*(om[6,-1]) to see which files would be collected.

See Glob Qualifiers for more about zsh's glob qualifiers.

  • Related