
私のUbuntuシステムでは、/var/www
名前が間違っているいくつかのファイルがWebルートフォルダに分散されています。
GermanyXXXs-enchanting....
次の出力を得るには、XXXをアポストロフィ'に置き換えたいと思います。
Germany's-enchanting....
次のコマンドはプレーン文字では機能しますが、エスケープしても引用符では機能しません。
find /var/www/html -name '*XXX*' -exec bash -c ' mv $0 ${0/XXX/\'}' {} \;
答え1
Bourneなどのシェルでは、一重引用符で囲まれた文字列内に一重引用符を使用することはできませ\'
ん。"'"
$'\''
また、bash
パラメータ拡張は、少なくともリストコンテキスト(コマンドのパラメータなど)で二重引用符で囲む必要があることも覚えておいてください。
再帰的に名前を変更する場合は、ファイル名も変更されていることを確認する必要があります。深さ優先ファイルのデフォルトの名前部分(ディレクトリコンポーネントではない)だけを名前変更します。
find /var/www/html -depth -name '*XXX*' -execdir bash -c '
ret=0
for file do
mv -- "$file" "${file/XXX/\'\''}" || ret=$?
done
exit "$ret"' bash {} +
この参照は外部参照'
です。\'
'...'
$file
"$file"
分割+グローブを避けるために、リストコンテキストで参照されます。$?
スカラー(リスト/配列ではない)変数への割り当てなので、参照は必要ありませんが、書き込みにret="$?"
問題はありません。
-execdir
(ここで使用されている$file
デフォルト名(./
一部のfind
実装によって接頭辞が付く可能性があります))は非標準拡張ですが、現在比較的広くサポートされていることに注意してください。
-execdir cmd {} +
(+
代わりに)を使用すると、;
いくつかfind
の実装では可能な限り複数のファイルを引数として呼び出そうとしますcmd
が、より重要なのは、cmd
終了状態(存在する場合)にエラーが報告されることを許可することです。find
あるいは、専用のバッチ名変更ツールを使用することもできます。たとえば、bashの代わりにzshを使用している場合は、zmv
自動ロード機能を使用できます。
autoload -Uz zmv
zmv '(**/)(*XXX*)' '$1${2/XXX/'\''}'
上記のすべての要素を考慮し、データの損失を防ぐために、事前にいくつかの完全性チェックを実行するのはなぜですか?
隠しファイルが残ります。名前を変更するには、次のように変更してください。
zmv '(**/)(*XXX*)(#qD)' '$1${2/XXX/'\''}'
テストを実行するための-n
オプションを追加できます。zmv
答え2
一重引用符ペア内の一重引用符は、一重引用符を閉じてを入力し、一重引用\'
符ペアを再起動してエスケープできます。
echo 'It isn't hard' # broken
echo 'It isn'\''t hard' # fixed
壊れた文字列を3つの単位'It isn'
と\'
合計に変換します't hard'
。別の方法で考えると、一重引用符'
内のすべての文字'...'
を置き換える必要があります'\''
。