如何使用 sed 从以零结尾的文件名列表中删除时间戳模式

如何使用 sed 从以零结尾的文件名列表中删除时间戳模式

查找比最新 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

相关内容