使用bash正则表达式重命名文件

86

可能是重复问题:
如何在Unix中一次性重命名多个文件

我想用正则表达式重命名一个文件夹中的所有文件(在名字末尾添加名称)并将它们移动到另一个文件夹。

我认为应该像这样:

mv -v ./images/*.png ./test/*test.png

但是它无法工作。

有人能给我提供一个解决方案吗?


2
基本上和许多其他问题一样 - 比如SO 1086502(https://dev59.com/rXNA5IYBdhLWcg3wHp-B)。甚至昨天还有一个人问了同样的问题。 - Jonathan Leffler
我不同意这本质上是一个重复的问题。我想使用正则表达式捕获,因为我的文件名像blah_blah_15_blah_blah_948ABCD.txt,对我来说重要的部分是第一个数字,而第二个数字是某种校验和。该捕获在https://dev59.com/13I-5IYBdhLWcg3wN1lD#1961273中显示。 - Fuhrmanator
4个回答

137

如果你使用的是Linux系统,请检查特殊的 rename 命令,该命令可以使用正则表达式进行重命名。

rename 's/^images\/(.+)/test\/$1.png/s' images/*.png
否则,请按照catwalk建议的方式编写一个针对文件名的bash循环。

7
有些系统可能称其为“prename”。 - Dennis Williamson
11
rename 's/_20/ /g' *.mp4:非常方便,无需记忆和打字,谢谢! - ptim
1
最好、最简单的方法就是这样做。虽然答案可能会像memeLab所做的那样进行编辑,以提供一些示例。 - Memke
4
也可通过Homebrew在Mac上获取,命令为brew install rename - Jeff Puckett
2
我来到这里是因为我想在目的名称中使用捕捉$1,通过s/blah_blah(\d\d)blah_blah([0-9A-F]{8})/$1/将文件从blah_blah_15_blah_blah_948ABCD1.txt重命名为15.txt - Fuhrmanator
显示剩余2条评论

70

试试这个:

for x in *.png;do mv $x test/${x%.png}test.png;done

5
如果文件名中有空格,你应该将变量名用引号括起来:for x in *.png; do mv "$x" "test/${x%.png}test.png"; done。这样可以确保命令正确地解析空格。 - Dennis Williamson
8
如果文件名包含空格,使用for循环无论是否用引号都会出现问题。因此最好使用生成器 | while read line; do something with "$line"; done 习惯用法。在这种情况下,可以使用以下命令:ls | grep '\.png$' | while read x; do ... ; done - just somebody
2
@justsomebody:在你的代码行前面简单地使用IFS=$'\n'; - MensSana
6
那不是使用通配符而不是正则表达式吗? - Kieveli
如果你“只是”设置了 IFS,为了下一个可能使用该机制的命令,请将其设置回之前的值。 - Michał Lepczyński
显示剩余4条评论

58
$ for old in ./images*.png; do
    new=$(echo $old | sed -e 's/\.png$/test.png/')
    mv -v "$old" "$new"
  done

3
我喜欢使用sed,因为它可以让我用任何我喜欢的东西替换它。在我的情况下,将“%20”替换为“ ”。我在正则表达式的末尾使用了'g'以实现全局替换:对于所有后缀为.pdf的文件进行循环,将文件名中的"%20"替换为" ",并将原始文件名更改为新名称。 - Marlon
2
谢谢!我从这里得出了这个一行代码 mv file_20name.mp4 "$(echo file_20name.mp4 | sed -e 's/_20/ /g')". - ptim
2
这样做非常漂亮,可以充分发挥sed正则表达式语法的威力。命令的组合非常棒,是许多其他bash脚本的良好原型。 - Paul
1
这对我所需的工作非常完美(从文件名中删除下划线)。for old in \ls`; do new=$(echo $old | sed -e 's/_//g'); mv "$old" "$new"; done` - Sean the Bean
我查看了“-e”标志的文档,但不理解它的作用。 - Daniel Kobe
我认为这是 sed 和其他 bash 程序的美丽组合。 - derek

5

还有一种解决方案是一个名为 mmv 的工具:

mmv "./images/*.png" "./test/#1test.png"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接