我需要从具有以下提到的条件的文件夹中删除所有文件。
文件名模式:fileNameBeginDateEndDate.txt
(YYYYMMDD 格式的开始和结束日期)
当前日期不在开始日期和结束日期之间的所有文件都需要删除。
例如,如果今天的日期是 2018-01-16,
- 需要删除的文件:
File2016010120170101.txt
- 不应删除的文件:
File2016010120190101.txt
提前致谢!
答案1
此过滤器只会输出符合您条件的文件名,即需要删除的文件名:
perl -MTime::Piece -ne 'BEGIN { $now=localtime->ymd("")} ($s,$e)=($_=~m/(\d{8})(\d{8})\./); print $_ if $e lt $now || $s gt $now'
例子:
echo "File2016010120170101.txt" | perl -MTime::Piece -ne 'BEGIN { $now=localtime->ymd("")} ($s,$e)=($_=~m/(\d{8})(\d{8})\./); print $_ if $e lt $now || $s gt $now'
File2016010120170101.txt
echo "File2016010120190101.txt" | perl -MTime::Piece -ne 'BEGIN { $now=localtime->ymd("")} ($s,$e)=($_=~m/(\d{8})(\d{8})\./); print $_ if $e lt $now || $s gt $now'
(nothing)
根据您获得初始文件名列表的方式,您可以预处理该列表,然后仅运行xargs rm
结果。
我建议根据您的文件调整正则表达式,使其尽可能严格。和/或在真正删除文件之前查看要删除的文件。
答案2
find
+bash
解决方案:
find -type f -regextype posix-egrep -regex ".*/File[0-9]{16}\.txt" -exec \
bash -c 'd=$0; f="$1"; [[ $f =~ File([0-9]{8})([0-9]{8})\.txt ]];
[[ "$d" -lt "${BASH_REMATCH[1]}" || "$d" -gt "${BASH_REMATCH[2]}" ]] && rm "$f"' \
$(date +"%Y%m%d") {} \;
答案3
和zsh
:
set -o extendedglob # best in ~/.zshrc
now=${(%):-%D{%Y%m%d}}
rm ./*[0-9](#c16).txt(e'{! ((now >= REPLY[-20,-13] && now <= REPLY[-12,-5] ))}'))
(%)
参数扩展标志,用于打开参数扩展的提示扩展。${:-value}
:类 Bourne${var:-value}
扩展的形式没有var
,因此它扩展为给定value
。%D{%Y%m%d}
: 提示扩展以该格式扩展至今天的日期。另一种方法是使用zmodload zsh/datetime; strftime -s now %Y%m%d $EPOCHSECONDS
或使用系统的date
命令:now=$(date +%Y%m%d)
。(#c16)
Extendedglob 运算符匹配前一个原子的 16 个(类似于 ksh93 的{16}([0-9])
)。(e:code:)
:glob 限定符,用于根据代码的评估来选择文件。REPLY[-20,-13]
:倒数 20 到倒数 13 个字符$REPLY
(保存正在检查的文件的路径)。