BASH:按名称分组并保留最后一个

BASH:按名称分组并保留最后一个

我希望一切对你都好。

我有一些这样的文件:

my_file_210804_2056_856.csv_20210804170806
my_file_210804_2056_856.csv_20211119181137
my_file_210805_2056_857.csv_20210805200847
my_file_210805_2056_857.csv_20211119181137
      ...

我想通过 unix 命令检索文件的最后版本。

例如对于文件210804我只想检索my_file_210804_2056_856.csv_20211119181137因为这是最后一次了。

感谢您的帮助

答案1

使用 GNU 版本的findsorthead( 使用 NUL 字符来分隔文件名 - NUL 是仅有的在路径/文件名中无效的字符,因此它是唯一可以安全地用作文件名分隔符的字符):

find . -maxdepth 1 -type f -name 'my_file_210804*' -print0 | sort -z -r | head -z -n 1

这适用于任何文件名,无论它们包含什么字符(包括空格、换行符等)。

如果您绝对确定文件名不包含也永远不会包含换行符,则可以使用换行符作为分隔符 --print0从命令中删除find,并-zsortand中删除选项head

find . -maxdepth 1 -type f -name 'my_file_210804*' | sort -r | head -n 1

如果文件名是纯文本文件(每行一个文件名),此变体也很有用:

sort -r filename-list.txt | head -n 1

如果您想按文件系统中的时间戳(而不是按文件名中嵌入的日期和时间)对文件名进行排序,则情况会稍微复杂一些。您需要使用-printf一个格式字符串,其中包括自纪元以来的修改时间戳(以秒为单位%T@)、制表符(\t)、文件名(%p)和 NUL(\0),而不仅仅是-print0

find . -maxdepth 1 -type f -name 'my_file_210804*' -printf '%T@\t%p\0' |
  sort -z -r -n -k 1,1 |
  cut -z -f2- |
  head -z -n 1

这里,sort ... -k1,1用于find对的输出进行排序第一的字段(时间戳),然后cut用于删除时间戳字段和将其与文件名分隔的制表符。


顺便说一句,您可能想解析ls. 不要这样做,它不起作用

相关内容