如何在Shell脚本中按文件名模式与修改日期筛选文件?
问题
我目录下有一批符合file.subfile.Q*.lastfile模式的文件,每个文件都有最后修改日期。我想编写一个Shell脚本,仅处理脚本输入参数指定日期对应的文件,该如何实现?
我了解可以通过stat命令匹配输入日期与文件修改日期,实现代码如下:
file_pattern="file.subfile.Q*.lastfile" files=$(ls $file_pattern 2>/dev/null) for file in $files; do last_modified_date=$(stat --format='%y' "$file" | cut -d' ' -f1) if [ "$last_modified_date" == "$input_date" ]; then echo "Processing file: $file (Last Modified: $last_modified_date)" else echo "Skipping file: $file (Last Modified: $last_modified_date)" fi done
为了提升性能,还可以添加如下条件提前过滤文件:
three_months_days=90 files=$(find . -maxdepth 1 -name "$file_pattern" -mtime -$three_months_days 2>/dev/null)
请问这种基于文件修改时间匹配的方式,和给源文件添加日期后缀再通过通配符捕获的方式相比,哪个更好?
回答
两种方式各有优劣,具体选择要看你的实际场景:
基于文件修改时间的方式
- 优点:无需改动现有文件命名规则,直接适配存量文件;不会出现文件名日期与实际内容不符的情况。
- 缺点:如果文件修改时间被意外篡改(比如批量调整文件时间的操作),会导致匹配错误;当文件数量极大时,逐个用
stat检查的性能会下降——虽然用find -mtime可以提前缩小范围,但-mtime是按天数偏移计算(比如-mtime 0指最近24小时),无法精确匹配指定日期,需要结合-newermt参数优化才能精准筛选:
这种写法可以直接输出目标文件,不需要后续循环判断,性能会比原脚本好很多。input_date="2024-05-20" # 精准筛选修改时间在指定日期当天的文件 find . -maxdepth 1 -name "file.subfile.Q*.lastfile" \ -newermt "$input_date 00:00:00" ! -newermt "$input_date 23:59:59"
文件名带日期后缀的方式
- 优点:匹配速度极快,直接用通配符(比如
file.subfile.Q*.20240520.lastfile)就能筛选,无需读取文件元数据;匹配逻辑直观,不受文件修改时间篡改的影响。 - 缺点:必须提前规范文件命名规则,所有目标文件都要加上正确的日期后缀;如果文件名中的日期与文件实际生成/修改日期不一致,会出现逻辑偏差(比如文件是昨天生成的,但后缀写了今天的日期)。
总结建议
如果你的文件命名可以规范,优先选择文件名带日期后缀的方式——尤其是文件数量较多的场景,性能和可靠性都更优。如果无法修改现有文件的命名规则,就用优化后的基于文件修改时间的方式,用find -newermt来精准筛选目标文件。
内容的提问来源于stack exchange,提问作者Ashwanth arul
相关产品推荐
相关产品推荐

