Unix Shell脚本:按文件名最后分隔字段(时间戳)排序文件
按文件名末尾时间戳排序的Shell解决方案
问题场景
需要遍历目录中一批末尾带有时间戳的文件,要求按文件名最后的时间戳(格式为YYYYMMDD_HHMMSS)排序。但文件名中包含的下划线数量不固定,使用ls *.txt | sort -t'_' -k3这类固定字段索引的命令无法生效。
示例文件名:
filename1_20230517_065806.txt filename2_20230517_055806.txt filename_3_20230517_125806.txt file_name_4_20230517_063806.txt
预期排序结果:
filename2_20230517_055806.txt file_name_4_20230517_063806.txt filename1_20230517_065806.txt filename_3_20230517_125806.txt
解决方案
方法1:使用sort的反向字段索引
sort命令支持从末尾倒数字段的语法,直接指定倒数第2到倒数第1个字段作为排序键,完美适配下划线数量不固定的场景:
ls *.txt | sort -t'_' -k -2,-1
-t'_':指定下划线为字段分隔符-k -2,-1:表示以倒数第2个字段(日期部分)到倒数第1个字段(时间部分)作为排序依据,不受前面下划线数量影响。
方法2:用awk提取排序键后再排序
如果系统sort版本不支持反向字段索引,可借助awk先提取时间戳部分,排序后还原文件名:
ls *.txt | awk -F'_' '{print $(NF-1)"_"$NF, $0}' | sort | cut -d' ' -f2-
awk -F'_' '{print $(NF-1)"_"$NF, $0}':提取倒数第2、1个字段拼接成时间戳,和原文件名一起输出sort:按时间戳排序cut -d' ' -f2-:去掉前面的时间戳,保留原文件名
脚本安全写法(避免解析ls输出)
在Shell脚本中,直接解析ls输出可能因文件名含特殊字符(如空格、换行)出问题,推荐用glob配合管道排序:
for file in *.txt; do echo "$file" done | sort -t'_' -k -2,-1
内容的提问来源于stack exchange,提问作者Sandy DeLeon
相关产品推荐
相关产品推荐

