このBashコマンドが括弧を置き換える正規表現を使用しないのはなぜですか?

このBashコマンドが括弧を置き換える正規表現を使用しないのはなぜですか?

Musicディレクトリ内のすべてのファイルとすべてのサブディレクトリを繰り返し、ファイル名の角かっこを括弧で置き換えるこのコマンドがあります。

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

しかし、これはうまくいきません。エラーを返さずに交換のみを実行しません。

キャラクターを正しく脱出していると思いました。私はどこで間違っていますか?

{}また、結局中かっこ、を括弧、に変更したいと思います()。中かっこにより複雑になる場合に備えて、今この内容に言及しなければならないと思いました。

答え1

うまくいかない理由がわかる唯一の理由は、名前にスペースがあるファイルがないことです。"* *"このパターンは、ファイル名にスペースが含まれている場合にのみ一致します。

名前に角かっこを含むファイルを見つけるには、次のようにします。

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

答え2

renameLinuxでこれを実装する2つの主な方法があります。

  • 付属のもの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}

関連情報