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
- First, let us use
find
with nulls to fetch the list of files. - Then use
xargs
to usestat
to prepend the unix time stamp. - Use
sort
to sort by oldest first. - Use
head
-n 3 to find all except the last 5. - Use
sed
to strip the temporary unix time stamp. - Use
tr
to convert the returns fromstat
to nulls again. - 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.