在带有 mv 的 bash 中使用正则表达式

Posted

技术标签:

【中文标题】在带有 mv 的 bash 中使用正则表达式【英文标题】:Use of regex in bash with mv 【发布时间】:2017-05-04 00:43:43 【问题描述】:

我有 4 个文件要重命名:

./01:
I0010001  I0020001

./02:
I0010001  I0020001

我想为每个文件添加辅助文件名.dcm,所以我尝试了:

$ mv \(*/*\) \1.dcm
mv: cannot stat '(*/*)': No such file or directory

$ mv \(./*/*\) \1.dcm
mv: cannot stat '(./*/*)': No such file or directory

$ mv \(./\*/\*\) \1.dcm
mv: cannot stat '(./*/*)': No such file or directory

$ mv "\(./*/*\)" "\1.dcm"
mv: cannot stat '\(./*/*\)': No such file or directory

$ mv 0\([1-2]\)/I00\([1-2\)]0001 0\1/I00\20001.dcm
mv: cannot stat '0([1-2])/I00([1-2)]0001': No such file or directory

$ mv "0\([1-2]\)/I00\([1-2\)]0001" "0\1/I00\20001.dcm"
mv: cannot stat '0\([1-2]\)/I00\([1-2\)]0001': No such file or directory

$ mv "0\([1-2]\)/I00\([1-2]\)0001" "0\1/I00\20001.dcm"
mv: cannot stat '0\([1-2]\)/I00\([1-2]\)0001': No such file or directory

$ mv "0\([[:digit:]]\)/I00\([[:digit:]]\)0001" "0\1/I00\20001.dcm"
mv: cannot stat '0\([[:digit:]]\)/I00\([[:digit:]]\)0001': No such file or directory

$ mv "0\([1-2]\)\/I00\([1-2]\)0001" "0\1/I00\20001.dcm"
mv: cannot stat '0\([1-2]\)\/I00\([1-2]\)0001': No such file or directory

$ mv \(*\) \1.dcm
mv: cannot stat '(*)': No such file or directory

它们都没有产生我想要的结果。

【问题讨论】:

所以你知道:你的问题是这些不是正则表达式:bash 中的明星使用globbing。这里的特殊区别在于没有捕获组:括号仅被视为文字。 【参考方案1】:

这里不需要正则表达式,这很简单,只需一个for 循环:

for f in 0[12]/I00[12]0001 ; do mv "$f" "$f.dcm" ; done

对于更复杂的情况,您应该查看rename 程序(在某些系统上为prename),它使用强大的 Perl 正则表达式来处理重命名。虽然这里没有必要,但这个简单的案例将使用:

pax> rename -n 's/$/.dcm/' 0[12]/I00[12]0001
rename(I01/I0010001, I01/I0010001.dcm)
rename(I01/I0020001, I01/I0020001.dcm)
rename(I02/I0010001, I02/I0010001.dcm)
rename(I02/I0020001, I02/I0020001.dcm)

-n 是调试模式(打印会发生什么但不要实际上重命名)。一旦你觉得它会做你想做的事,就把它移除。

【讨论】:

这并不能真正回答问题。也许将故障排除作为观察并主要解释如何将正则表达式与mv 一起使用会更好 @LTKills,虽然问题 title 要求使用正则表达式,但它(就像许多 XY 问题一样)完全没有必要。 实际 问题是如何以特定方式重命名文件。如果有人问如何在汇编程序中编写会计包,在 COBOL 中编写操作系统,或者在 php 中编写 anything,这并没有什么不同 :-) 我同意@gmelodie。标题“使用 mv 在 bash 中使用正则表达式”期望得到与该特定问题相关的答案。 @Sylvain,如果你问木匠如何用锤子切割一些木头,只有最虐待狂或精神错乱的人才会提出任何建议,而不是放下锤子并使用锯子 :-) 问题这里不是如何使用mv(尽管它看起来像),而是如何以某种方式重命名文件。我建议 OP 也采用这种思维方式,因为他们接受了答案。

以上是关于在带有 mv 的 bash 中使用正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

Perl:转义字符串中的特殊字符以匹配正则表达式

在 bash 的 if 条件中使用正则表达式

如何在 bash 脚本中使用正则表达式?

如何在 bash 脚本中使用正则表达式否定测试?

如何在 bash 脚本中使用正则表达式否定两个逻辑测试?

在普通bash中使用正则表达式提取子字符串