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

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

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

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

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

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

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

答案1

了解 Perlrename工具:

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

在线手册页, 还看到这个问题

该正则表达式表示要匹配波浪号,即许多不是点的字符,但至少有一个;并替换与空字符串匹配的任何内容。删除-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)

或者仅使用 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

再次删除 来echo实际进行重命名。

答案2

在bash中:

shopt -s globstar
for file in **/*~[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]*
do
  echo mv -- "$file" "${file/~[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]/}"
done

这会(递归地)找到与日期模式(后跟波形符)匹配的所有文件名,然后回显示例mv命令以重命名它们。 mv 命令的目标是 bash 参数扩展的结果,它将任何波浪号日期字符串文本替换为空。

答案3

代码:

echo "ABCDEF~20160531-162719" | sed "s/~.*//g"
echo "Letter to Client 27May2016~20160531-162719.pdf" |sed "s/~.*[^.pdf]//g"

以上命令达到了上述结果

相关内容