我想制作一个linux命令,只保留最近的5个文件,但这些文件必须以REF开头,并删除其他以REF开头的文件,但不能接触其他文件。例如:在我的文件夹中,我有:
-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
该命令应仅删除:
-rw-r--r-- 1 0 Jan 1, 2022 REF_1
-rw-r--r-- 1 0 Feb 1 2022 REF_2
并应保留其他文件。我尝试了ls -t REF* | head -n+4 | xargs rm REF*
,但此命令删除了所有以REF开头的文件!
我可以使用什么命令?
使用zsh(可在许多Linux发行版上使用,也可在AIX上从IBM的AIX开放源代码软件工具箱中获得(,您可以简单地:
rm REF*(om[6,-1])
这使用zsh强大的globbing(文件名生成(功能来:
- 收集以
REF
开头的文件列表 - 使用
(om...)
按修改时间(最新的第一个(对文件进行排序 - 用
[6,-1]
选择第6个和剩余的文件,保留最新的5个文件 - 将该文件列表传递给
rm
首先用一个简单的print -l REF*(om[6,-1])
测试它,看看会收集哪些文件。
有关zsh的Glob限定符的更多信息,请参阅glb限定符。
提到了Logrotate,为什么不使用它呢
它无法处理分隔符是下划线(_(的情况。
$ cat log.conf
REF* {
rotate 5
}
% logrotate log.conf
error: log.conf:1 keyword 'REF' not properly separated, found 0x2a
这是一个完整的脚本,带有安全的文件名
find . -name 'REF_*' -print0 |
xargs -0 stat -c "%Y %n" |
sort -n |
head -n+3 |
sed -e 's/^[0-9]* //' |
tr '12' ' ' |
xargs -0 rm
- 首先,让我们使用带有null的
find
来获取文件列表 - 然后使用
xargs
来使用stat
来准备unix时间戳 - 使用
sort
先按最旧的排序 - 使用
head
-n+3查找除最后5个之外的所有值 - 使用
sed
剥离临时unix时间戳 - 使用
tr
将stat
的返回值再次转换为null - 最后
xargs
删除不需要的文件