到查找比最新 8 个文件更旧的文件我在用着:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rz | sed -z 1,8d
该-printf '%T@ %p\0'
命令应用上次修改的时间戳(表示为自 1970 年 1 月 1 日 00:00 GMT 以来的秒数,包含小数部分)到每个零终止文件名匹配,例如:
1597765267.7628475560 ./fileName2.txt1597765264.0267179360 ./fileName1.txt
为了通过管道删除这些最旧的文件xargs -0 gio trash
,我需要删除时间戳。因此我添加另一个 sed 命令来执行此操作:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rz | sed -z 1,8d | sed -z "s/^[0-9]*.[0-9]* //g"
现在我得到了正确的输出,但是有没有更好更有效的方法呢?
根据@Quasímodo 的回答,我尝试使用 sed 删除模式格式进一步简化(因为我实际上并没有替换任何东西),但没有得到任何输出:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rnz | sed -z "1,8d; /^[0-9]*\.[0-9]* /d"
欢迎提出任何建议。
结论(来自多个回复):
find $targetPath -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rnz | sed -z "1,${retain}d; s/^[^ ]* //"
在哪里:
$targetPath,查找文件的目录,例如当前目录“。”
${retain},要保留的最新文件数,例如 8
答案1
由于您可以控制输出,因此删除时间戳非常容易。您知道每个\0
-delineated 记录都将以时间戳开头,然后是空格。因此,您需要做的就是删除所有非空格字符,直到第一个空格:
find . -maxdepth 1 -type f -printf '%T@ %p\0' |
sort -rz | sed -z '1,8d; s/^[^ ]* //'
但是,您可能想要按数字排序,并且您可能只按第一个字段排序,而不需要按文件名排序。因此,这将为您提供 8最老的文件:
find . -maxdepth 1 -type f -printf '%T@ %p\0' |
sort -rznk1,1 | sed -z '1,8d; s/^[^ ]* //'
答案2
将两个 Sed 进程转换为一个。
sort -zrn | sed -z "1,8d; s/^[0-9]*\.[0-9]* //"
已应用更正:
- 进行
n
数字排序。 .
匹配任意字符,它应该\.
在正则表达式中。g
替换记录中的所有匹配项。您只需对每条记录进行一次替换(即删除时间戳),因此删除该g
。此修改还可以提高性能。
您的尝试sed -z "1,8d; /^[0-9]*\.[0-9]* /d"
失败,因为/^[0-9]*\.[0-9]* /d
删除每一行匹配正则表达式。这与s/^[0-9]*\.[0-9]* //
删除字符串匹配正则表达式。
答案3
您可以将find
命令与 GNU 一起使用awk
:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -zrn | awk 'BEGIN{RS=ORS="\0"} NR>8 {sub(/[^ ]+ /, ""); print}'
这里:
我们将输入记录分隔符(
RS
)和输出记录分隔符(ORS
)设置为\0
。对于从第 8 条记录开始的每条记录 (
NR>8
),我们将第一个空格之前的所有内容(包括第一个空格)替换为空字符串 (sub(/[^ ]+ /, "")
),然后打印该记录 (print
)。谢谢@卡西莫多对上述命令提出改进建议。
例子:
$ touch {01..15}.txt
$ ls
01.txt 02.txt 03.txt 04.txt 05.txt 06.txt 07.txt 08.txt 09.txt 10.txt 11.txt 12.txt 13.txt 14.txt 15.txt
$ find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -zrn | awk 'BEGIN{RS=ORS="\0"} NR>8 {sub(/[^ ]+ /, ""); print}'
./07.txt./06.txt./05.txt./04.txt./03.txt./02.txt./01.txt