私が望む結果は、ディレクトリを再帰的に検索し、見つかったすべてのファイルで特定の文字列を探すことです。次のコマンドは、私が通常使用するコマンドです。
find ./ | xargs grep -ns 'foobar'
ただし、foobar
引用符が付いている場合、コマンドは失敗し、>
シェルにプロンプトが表示されます。問題の原因となっている具体的なコマンドは次のとおりです。
find ./ | xargs grep -ns 'add_action(\'save_post\','
バックスラッシュで引用符をエスケープしようとしましたが、うまくいきませんでした。正しい方法は何ですか?
答え1
シングルクォートはシングルクォートで終了し、その間にある他の文字はバックスラッシュも含めてそのまま保持されます。したがって、シングルクォートの間にシングルクォートを埋め込むことはできません。(ただし、できる一重引用符を終了し、一重引用符をエスケープし、新しい一重引用符のセットを開始します。例: 'Single quotes aren'\''t ever really embedded in single quotes.'
)
提案:grep -r pattern .
現在のディレクトリを再帰的に grep できる場合は、find+xargs を避けてください。
以下のコマンドは同等の動作をします。
grep -rns "add_action('save_post'," .
grep -rns 'add_action('\'save_post\', .
最後のコマンドは次のように解釈されます。
'add_action('
->add_action(
\'
->'
save_post
->save_post
\'
->'
,
->,
これらの部分を連結すると、grep
コマンドは引数を受け取りますadd_action('save_post',
。
答え2
xargs
find
は、 を生成しない奇妙な方法で引用された引数を想定しています。ファイル名に または空白が含まれていないことがわかっている場合を除き、xargs
と組み合わせて使用しないでください。find
\"'
を使用する代わりにxargs
、find
実行するプログラムを直接呼び出します。
find . -exec grep -ns 'add_action('\''save_post'\'',' {} +
exec … {} +
を使用すると、 と同様に、プログラムは一度に複数のファイルに対して 1 回呼び出されますxargs
。 の古いバージョンの一部ではここ¹ がfind
サポートされていないため+
、代わりに を使用する必要があります。;
これはgrep
ファイルごとに 1 回呼び出されます。
find … -print0 | xargs -0
ユーティリティがサポートしている場合は、代わりに を使用することもできます¹。 この-print0
オプションは、find
ヌルバイトで区切られた名前を出力するように指示し、 はヌルで区切られた入力を期待し、引用符の解釈を行わないように-0
指示します。xargs
上記の引用符に注意してください。単一引用符で囲まれたすべての文字は、'
リテラル文字列の終了を示す を除いて、文字通りに解釈されます。したがって、これは'\''
実質的に、単一引用符で囲まれた文字列内にリテラル単一引用符を配置する方法です。正式には、「'
引用符の終了、\
リテラル'
単一引用符、'
引用符の開始」となります。
の特殊なケースではgrep
、実装がサポートしていれば¹、 を省略してfind
、 を使用してgrep -r
ディレクトリ内を再帰的に検索できます。
grep -r 'add_action('\''save_post'\'',' .
¹ Linux、Cygwin、FreeBSD、OSX はこれらの機能をサポートしています。
答え3
grep "add_action('save_post'," ./* -R
オプションを使用して、現在のディレクトリ内のすべてのファイルを再帰的に grep できます
-R
。検索文字列は で囲むことができます
"
。