从文件名中递归删除日期和时间

从文件名中递归删除日期和时间

我有一个文件夹,其中包含以下形式的文件的文件夹

resultstatsDF_iris_2017-05-26--21-33-35-437096_methodnr-2_percentage-0.05_seed-0.wcr

我想删除其中每个的日期和时间,所以在这种情况下得到

resultstatsDF_iris_methodnr-2_percentage-0.05_seed-0.wcr

我如何在 bash 中执行此操作?

答案1

如果你真的想做的话“用bash”, 然后

find . -name '*.wcr' -execdir bash -c '
  shopt -s extglob; for f; do echo mv -- "$f" "${f/_+([0-9-])_/_}"; done
' bash {} +

+([0-9-])这依赖于匹配集合中出现的一个或多个字符的扩展 glob[0-9-]

您可以使替换更加具体,例如,${f/_2017+([0-9-])_/_}如果简单地匹配数字和破折号过于通用。

注意:删除 echo 一旦你确定它正在做你想做的事。

答案2

使用find+prename(Perl 重命名)命令:

find yourfolder -type f -name "*.wcr" -exec prename 's/^(.+)_[0-9]{4}-[0-9]{2}-[0-9]{2}[^_]+(_.*)$/$1$2/' {} +

要查看prename结果而不执行操作,请添加-n选项 (打印要重命名的文件的名称,但不重命名):

man rename

  • [0-9]{4}-[0-9]{2}-[0-9]{2}- 模式指向日期-like 子串(例如2017-05-26

答案3

使用Perl 重命名命令(任一变体,但不是 util-linux rename):

find . -type f -name \*.wcr -exec rename 's/_\d{4}-(\d{2}-){2}-(\d{2}-){3}\d+_/_/' {} +

答案4

如果文件始终是一层目录深度,那么您可以使用类似for x in */*_20*_*.使用哪种模式取决于可能存在您不想重命名的其他文件。我刚刚给出的模式假设日期以 开头20,并且名称包含的所有文件_20以及之后的另一个取消划线都应该重命名。

您可以使用 shell 循环进行重命名参数扩展构造来构建新的文件名。

for old_name in ./*/*_20_*_*; do
  base=${old_name##*/}        # remove the directory part
  prefix=${base%%_20*}        # remove everything from _20
  suffix=${base#*_20}         # remove everything up to _20
  suffix=${suffix#*_}         # ... then everything before the first remaining _
  mv "$old_name" "${old_name%/*}/${prefix}_${suffix}"
done

如果文件的深度不同,在 bash ≥4.3 中,您可以运行shopt -s globstarthen for x in **/*_20*_*; …。这图案**globstar如果打开,则匹配任何目录深度。这也适用于 bash 4.0–4.2,但需要注意的是它还会遍历目录的符号链接。这也适用于 zsh 和 ksh,无需任何警告,在 zsh 中开箱即用,set -o globstar在 ksh 中也适用。

相关内容