我有这个命令来遍历Music
目录中的所有文件和所有子目录,并将文件名中的任何方括号替换为圆括号:
find /home/Music/ -depth -name "* *" -execdir rename 's/\[/\(/g' "{}" \;
但这不起作用。它不会返回任何错误,只是不进行替换。
我以为我正确地逃离了角色。我哪里错了?
另外,最终我还想用圆括号 , {}
, 替换大括号 , ()
, 。只是想我现在会提到这一点,以防大括号带来更多复杂性。
答案1
我能看出它不起作用的唯一原因是如果名称中没有包含空格的文件。"* *"
仅当文件名包含空格时该模式才会匹配。
如果你想查找名称中包含方括号的文件,请执行以下操作
find /home/Music/ -depth -name "*[*" -execdir rename 's/\[/\(/g' "{}" \;
答案2
rename
Linux上主要有两种实现方式:
- 附带的那个
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}