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
由于您控制输出,因此删除时间戳非常容易。您知道每个\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)
将两个 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]* //
这与删除与正则表达式匹配的字符串不同。