基于Bash脚本提取并排序文件名中日期与后缀的技术咨询
没问题!我来手把手教你用cut、sed、sort(再加个常用的uniq做去重)实现你的需求,分两部分拆解,每步都给具体命令和解释:
一、提取去重并排序的日期
首先得明确你的文件名格式,比如常见的report_2024-05-15.pdf、data_20240514.csv这类,我分两种场景给你方案:
场景1:日期是固定分隔符的字段
如果日期是文件名里用固定符号(比如下划线、连字符)分隔的某一段,比如前缀_YYYY-MM-DD.后缀,用cut最直接:
# 列出所有目标文件(比如所有txt、csv),提取第2个下划线后的字段,排序去重后存入文件 ls *.txt *.csv | cut -d '_' -f 2 | sort | uniq > unique_sorted_dates.txt
ls *.txt *.csv:列出你需要处理的所有文件cut -d '_' -f 2:按下划线_分割文件名,提取第2个字段(就是日期部分)sort:对提取出的日期排序(YYYY-MM-DD格式的话,普通字典序和日期顺序一致,完美适配)uniq:去除重复的日期(注意uniq必须接在sort后面,因为它只识别连续的重复项)> unique_sorted_dates.txt:把结果写入指定文件,不需要的话可以删掉这部分直接输出到终端
场景2:日期是固定格式的字符串(位置不固定)
如果日期在文件名里的位置不固定,但格式是YYYY-MM-DD或者YYYYMMDD,用sed正则捕获更靠谱:
# 用正则匹配YYYY-MM-DD格式的日期,排序去重后保存 ls *.pdf *.xlsx | sed -E 's/.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*/\1/' | sort | uniq > dates.txt
sed -E 's/.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*/\1/':用扩展正则匹配任意字符后接4位数字-2位数字-2位数字的日期,把整个文件名替换成捕获到的日期部分- 后面的
sort和uniq作用和上面一样
二、提取并排序的文件后缀
提取后缀同样分两种情况,适配普通后缀和多级后缀(比如.tar.gz):
方案1:提取所有后缀(含多级)
如果要保留.tar.gz这种完整后缀,用cut取最后一个点之后的所有内容:
# 提取所有目标文件的后缀,去重排序后保存 ls *.txt *.tar.gz *.pdf | cut -d '.' -f 2- | sort | uniq > sorted_extensions.txt
cut -d '.' -f 2-:按点.分割文件名,从第2个字段开始取到最后,这样.tar.gz会被完整提取成tar.gz
方案2:仅提取最后一级后缀
如果只需要最后一级后缀(比如.tar.gz只取gz),用sed更简单:
# 提取最后一级后缀,排序后保存(不需要去重就删掉uniq) ls *.txt *.tar.gz *.csv | sed -E 's/.*\.//' | sort | uniq > extensions.txt
sed -E 's/.*\.//':把文件名中最后一个点.之前的所有内容替换为空,留下最后一级后缀
一些实用注意事项
- 如果文件名里有空格,别用
ls,换成find避免出错:比如find . -maxdepth 1 -type f -name "*.*"代替ls *.txt - 如果日期格式是
DD/MM/YYYY这种非标准格式,排序时要指定规则:sort -k1.7,1.10 -k1.4,1.5 -k1.1,1.2(先按年排序,再按月,最后按日) - 要处理子目录里的文件?把
ls换成find . -type f -name "你的文件匹配模式"就行,比如find . -type f -name "*.log"
内容的提问来源于stack exchange,提问作者Celentano
相关产品推荐
相关产品推荐

