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

Bro*_*rde 6 command-line bash sed

查找比我正在使用的最新 8 更旧的文件

find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rz | sed -z 1,8d
Run Code Online (Sandbox Code Playgroud)

-printf '%T@ %p\0'命令将最后修改的时间戳(表示为自 1970 年 1 月 1 日,格林威治标准时间 00:00 以来的秒数,带有小数部分)到匹配的每个以零结尾的文件名的开头,例如:

1597765267.7628475560 ./fileName2.txt1597765264.0267179360 ./fileName1.txt
Run Code Online (Sandbox Code Playgroud)

为了通过管道删除这些最旧的文件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"
Run Code Online (Sandbox Code Playgroud)

现在我有正确的输出,但是有没有更好更有效的方法?


基于@Quasímodo 的回答,我尝试通过使用 sed 删除模式格式进一步简化(因为我实际上并没有替换任何内容),但我没有得到任何输出:

find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rnz | sed -z "1,8d; /^[0-9]*\.[0-9]* /d"
Run Code Online (Sandbox Code Playgroud)

任何建议表示赞赏。

结论(来自多个回复):

find $targetPath -maxdepth 1 -type f -printf '%T@ %p\0' | sort -rnz | sed -z "1,${retain}d; s/^[^ ]* //"
Run Code Online (Sandbox Code Playgroud)

其中
$targetPath,查找文件的目录,例如当前目录“.”
${retain},要保留的最新文件数,例如 8

ter*_*don 5

由于您控制输出,因此删除时间戳非常容易。您知道每个\0-delineated 记录将以时间戳开头,然后是一个空格。所以你需要做的就是删除所有非空格字符,直到第一个空格:

find . -maxdepth 1 -type f -printf '%T@ %p\0' | 
    sort -rz | sed -z '1,8d; s/^[^ ]* //'
Run Code Online (Sandbox Code Playgroud)

但是,您可能需要数字排序,也可以只对第一个字段进行排序,而无需对文件名进行排序。因此,这将为您提供 8 个最旧的文件:

find . -maxdepth 1 -type f -printf '%T@ %p\0' | 
    sort -rznk1,1 | sed -z '1,8d; s/^[^ ]* //'
Run Code Online (Sandbox Code Playgroud)


Qua*_*odo 4

将两个 Sed 进程转换为一个进程。

sort -zrn | sed -z "1,8d; s/^[0-9]*\.[0-9]* //"
Run Code Online (Sandbox Code Playgroud)

应用更正:

  • 进行n数字排序。
  • .匹配任何字符,它应该\.在正则表达式中。
  • g替换记录中的所有匹配项。您只需要从每个记录中进行一次替换(即删除时间戳),因此删除该g. 此修改还提高了性能。

您的尝试sed -z "1,8d; /^[0-9]*\.[0-9]* /d"失败,因为/^[0-9]*\.[0-9]* /d删除了与正则表达式匹配的每一行。s/^[0-9]*\.[0-9]* //这与删除与正则表达式匹配的字符串不同。