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

时间:2013-02-13 17:26:49

标签: regex bash copy rename

我的文件结构如下:

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}

有人可以告诉我该怎么做吗?

5 个答案:

答案 0 :(得分:19)

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

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

答案 1 :(得分:10)

以下是使用find命令的解决方案:

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

此命令实际上并不进行出价,只会打印出应该执行的操作。查看输出,如果您满意,请删除echo命令并将其运行为真实。

答案 2 :(得分:0)

Brace扩展如:

{*/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

然后这似乎是正确的工具=)

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

将其设为Debian的默认设置和Ubuntu的衍生产品:

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

只想添加爆炸丸的答案。 但是在OS X上,你必须说

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

或者mv命令无法识别它。