在bash中使用正则表达式复制和重命名多个文件



我有一个文件结构,看起来像:

A/
    2098765.1ext
    2098765.2ext
    2098765.3ext
    2098765.4ext
      12345.1ext
      12345.2ext
      12345.3ext
      12345.4ext
B/
    2056789.1ext
    2056789.2ext
    2056789.3ext
    2056789.4ext
      54321.1ext
      54321.2ext
      54321.3ext
      54321.4ext

我需要将所有以20开头的文件重命名为以10开头;即,我需要将B/2022222.1ext重命名为B/1022222.1ext

我看到了许多关于重命名多个文件的其他问题,但似乎无法解决我的问题。只是想看看我是否能在真正尝试复制/重命名之前弄清楚我在做什么:

for file in "*/20?????.*"; do
    echo "{$file/20/10}";
done

但我得到的只是

{*/20?????.*/20/10}

有人能教我怎么做吗?

你只是有一点不正确的语法就是:

for file in */20?????.*; do mv $file ${file/20/10}; done
  1. in的参数中删除引号。否则,不会进行文件名扩展
  2. 替换中的$应在括号前

这里有一个使用find命令的解决方案:

find . -name '20*' | while read oldname; do echo mv "$oldname" "${oldname/20/10}"; done

这个命令实际上并不执行您的命令,它只打印出应该执行的操作。查看输出,如果您满意,请删除echo命令并实际运行它。

只想添加到爆炸药丸的答案中。不过,在OS X上,你必须说

mv "${file}" "${file_expression}"

或者mv命令无法识别它。

支撑展开,如:

{*/20?????.*/20/10}

不能用引号括起来。

相反,尝试(使用Perl rename):

rename 's/^10/^20/' */*.ext 

您可以在shell提示符下使用Perl工具rename来执行此操作。(还有其他同名工具可能无法做到这一点,所以要小心。)

如果要进行试运行以确保不会破坏任何文件,请在命令中添加-n开关。

注释

如果运行以下命令(linux

$ file $(readlink -f $(type -p rename))

你会得到一个类似的结果

.../rename: Perl script, ASCII text executable

那么这似乎是正确的工具=)

这似乎是Ubuntu上的默认rename命令。

使其成为Debian和类似Ubuntu的衍生物的默认值:

sudo update-alternatives --set rename /path/to/rename

*的glob行为被抑制在双引号中。尝试:

for file in */20?????.*; do
    echo "${file/20/10}";
done

最新更新