为什么这个使用正则表达式的 Bash 命令没有替换我的括号?

为什么这个使用正则表达式的 Bash 命令没有替换我的括号?

我有这个命令来遍历Music目录中的所有文件和所有子目录,并将文件名中的任何方括号替换为圆括号:

find /home/Music/ -depth -name "* *" -execdir rename 's/\[/\(/g' "{}" \;

但这不起作用。它不会返回任何错误,只是不进行替换。

我以为我正确地逃离了角色。我哪里错了?

另外,最终我还想用圆括号 , {}, 替换大括号 , (), 。只是想我现在会提到这一点,以防大括号带来更多复杂性。

答案1

我能看出它不起作用的唯一原因是如果名称中没有包含空格的文件。"* *"仅当文件名包含空格时该模式才会匹配。

如果你想查找名称中包含方括号的文件,请执行以下操作

find /home/Music/ -depth -name "*[*" -execdir rename 's/\[/\(/g' "{}" \;

答案2

renameLinux上主要有两种实现方式:

  • 附带的那个perl(可能是您期待的那个)
  • util-linux 附带的一个(可能是您拥有的那个)。

附带的语法util-linux是:

find ... -execdir rename '[' '(' {} +

但是,这只会替换一次出现的[.

perl可能会在您的系统上rename被调用prename

替代方案rename是 zsh 的zmv.它将首先处理降序目录深度并避免冲突问题。

在 zsh 中:

autoload zmv
zmv '(**/)(* *)' '$1${2//\[/(}'

并将{}和转换[]()

zmv -n '(**/)(* *)' '$1${${2//[]\}]/)}//[[{]/(}'    

答案3

以下应该有效:

for i in `find o -type f`; do new="${i/\[/(}" ; if [ "${i}" != "${new}" ]; then mv ${i} ${new} ; echo "Moving ${i} to ${new}"; fi ; done

如果文件名包含空格,请尝试以下操作:

OLDIFS=${IFS} ; IFS=$(echo -en "\n\b") ; for i in `find o -type f`; do new="${i/\[/(}" ; if [ "${i}" != "${new}" ]; then mv ${i} ${new} ; echo "Moving ${i} to ${new}"; fi ; done; IFS=${OLDIFS}

相关内容