递归地从文件名中删除字符

fil*_*oes 5 rename

我有数百个目录,有些嵌套在其他目录中,有数万个文件。文件需要删除日期/时间戳。

一个示例文件名是Letter to Client 27May2016~20160531-162719.pdf,我希望它恢复原状Letter to Client 27May2016.pdf

另一个示例文件名是ABCDEF~20160531-162719,我希望它恢复为ABCDEF. 请注意,与上面的示例不同,此文件没有扩展名。

我需要一个可以在受影响文件夹的根目录下运行的命令,该命令将递归遍历并查找/修复文件名。

(我使用 Syncthing 来同步文件,并通过将它们从.stversions目录复制回原来的位置来恢复已删除的文件,但发现 Syncthing 附加了该日期/时间戳......)

ilk*_*chu 5

认识 Perlrename工具:

$ rename -n -v  's/~[^.]+//' *~*
rename(ABCDEF~20160531-162719, ABCDEF)
rename(Letter to Client 27May2016~20160531-162719.pdf, Letter to Client 27May2016.pdf)
Run Code Online (Sandbox Code Playgroud)

在线手册页,另见此 Q

那个正则表达式说要匹配波浪号,尽可能多的不是点的字符,但至少是一个;并替换与空字符串匹配的任何内容。删除-n以实际进行替换。我们可以将模式更改~[-0-9]+为仅替换数字和破折号。

抱歉,您说的是“递归”,所以让我们使用find

$ find -type f -name "*~*" -execdir  rename -n -v  's/~[-0-9]+//' {} +
rename(./ABCDEF~20160531-162719, ./ABCDEF)
rename(./Letter to Client 27May2016~20160531-162719.pdf, ./Letter to Client 27May2016.pdf)
Run Code Online (Sandbox Code Playgroud)

或者只使用 Bash 或 ksh,尽管~后跟数字的目录会破坏这一点:

$ shopt -s extglob       # not needed in ksh (as far as I can tell)
$ shopt -s globstar      # 'set -o globstar' in ksh
$ for f in **/*~* ; do 
    g=${f//~+([-0-9])/}; 
    echo mv -- "$f" "$g" 
  done
mv -- ABCDEF~20160531-162719 ABCDEF
mv -- Letter to Client 27May2016~20160531-162719.pdf Letter to Client 27May2016.pdf
Run Code Online (Sandbox Code Playgroud)

同样,删除echo以实际进行重命名。