在 bash 中使用正则表达式复制和重命名多个文件
Posted
技术标签:
【中文标题】在 bash 中使用正则表达式复制和重命名多个文件【英文标题】:Copy and Rename Multiple Files with Regular Expressions in bash 【发布时间】:2013-01-29 08:11:07 【问题描述】:我的文件结构如下:
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
谁能告诉我怎么做?
【问题讨论】:
文件 glob 不是正则表达式。 好吧,我想使用正则表达式,因为我不知道如何使它适用于 glob。 【参考方案1】:*
的全局行为在双引号中被抑制。试试:
for file in */20?????.*; do
echo "$file/20/10";
done
【讨论】:
这只是将“/20/10”附加到每个文件名。【参考方案2】:只是想添加到爆炸丸的答案。 不过在 OS X 上,你必须说
mv "$file" "$file_expression"
或者mv
命令无法识别它。
【讨论】:
【参考方案3】:大括号扩展如:
*/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
【讨论】:
有没有办法让rename
进行试运行,以便在我做之前知道它在做什么?我不想弄乱我已经拥有的东西。【参考方案4】:
这是一个使用find
命令的解决方案:
find . -name '20*' | while read oldname; do echo mv "$oldname" "$oldname/20/10"; done
此命令实际上并不执行您的命令,它仅打印出应该执行的操作。查看输出,如果您满意,请删除 echo
命令并真正运行它。
【讨论】:
希望我能接受两个答案。我选择了另一个,因为它更简单。【参考方案5】:你只是有一点语法错误而已:
for file in */20?????.*; do mv $file $file/20/10; done
-
从
in
的参数中删除引号。否则,文件名扩展不会发生。
替换中的$
应该放在括号之前
【讨论】:
喜欢这种简单的方法。 您知道有一个页面解释了适用于$file/20/10
的正则表达式/通配符规则的类型吗?似乎正则表达式和 bash 通配符有时会发生冲突以上是关于在 bash 中使用正则表达式复制和重命名多个文件的主要内容,如果未能解决你的问题,请参考以下文章
管道字符串与变量中的文件夹到 findstr - 复制和重命名文件