私はC:\
両方の異なる種類のファイルを/root
。
私の木は次のとおりです
- Batch
- Place of the script
- Conf
- Appli1
- File1.xml
- File2.xml
- ...
- Appli2
- File1.xml
- File2.xml
- ...
- ...
- Info
- File1.conf
- File2.conf
- ...
私のスクリプトは次のとおりです/Batch
。
#/bin/bash
find ../ -name "*.xml" -o name "*.conf" -print | xargs sed -i 's C:\ /root/ g'
しかし、エラーがありますsed part
。character 14: command 's' unfinished
なぜこれが起こるのですか?
答え1
どこで使用しますか:
sed -i 's C:\ /root/ g'
あなたは使用していますs
注文するコマンドのいくつかの部分をスペース文字で区切ることはまれですが、完全に有効です。ただし、区切り文字の前にバックスラッシュがある場合は、区切り文字として扱われず、パラメータ自体の一部として扱われます。
ここでの問題は、バックスラッシュがC:\
中間の空白を超えているため、代替のs
終わりが見つからず(現在ではg
)見てわかるように、コマンドが完了していないと文句を言うことです。
少なくとも別のバックスラッシュを使用してバックスラッシュ自体をエスケープする必要があります。
sed -i 's C:\\ /root/ g'
スペースを別の文字に置き換える方がはっきりするかもしれませんが、これはうまくいきます。
あなたの用途に関してxargs
とサブディレクトリ -xargs
ここでは必要ありません。find
サブディレクトリのファイル処理を含め、これを直接実行できます。使用:
find ../ \( -name "*.xml" -o -name "*.conf" \) -exec sed -i -e 's|C:\\|/root/|g' '{}' +
find
コマンドsed
自体と見つかったすべてのファイル名を実行します。代わりにファイル名を挿入すると、コマンドの実行回数が最小限に抑え{}
られます。+
find
-execdir
-exec
おそらく、説明されているいくつかのセキュリティ上の理由よりも良いでしょう。find
マニュアルページ;非標準の拡張ですが、GNUツールを使用しているようなので、必要に応じてください。
答え2
これはバックスラッシュです。バックスラッシュは次の文字を破壊し、特別な意味を失います。 sedコマンドはユーザーが入力した内容を読み取ります(ここではsed式のみを使用し、退屈なシェルコマンドライン全体を実行しません)。
s
<SPACE>
C
:
Literal <SPACE>
/root/
<SPACE>
検索のための式として使用したいトークンとその置換をsedに指示しました。しかし、sedは次のようなものを見たいと思います:
s
<SPACE>
C
:
Literal \
<SPACE>
/root/
<SPACE>
バックスラッシュをリテラルバックスラッシュに置き換えるには、バックスラッシュの前にバックスラッシュを追加します。
sed -e 's C:\\ /root '
個人的にはスペースを使用しないことをお勧めします。私は|
同じものを使用するか;
。しかし、バックスラッシュにはまだ問題があります。本当に興味深いのは、バックスラッシュを区切り文字として使用するために入力する必要があることを見つけることです。 :)