grep この変数のパターンを誤って読み込みます。

grep この変数のパターンを誤って読み込みます。

エスケープパターンの入力に問題がありますgrep

私のテストファイルは次のとおりです

export_cc = ${dir}/aaa/bbb/ccc
export_cc = ${dir}/aaa/bbb/eee
export_cc = ${dir}/aaa/bbb/ddd
export_cc = ${dir}/aaa/bbb/fff
export_cc = ${dir}/aaa/bbb/ggg

私が実行した場合:

~/programming/sandbox $ printf %q 'export_cc = ${dir}/aaa/bbb/ccc'
export_cc\ =\ \$\{dir\}/aaa/bbb/ccc

その後、出力をgrepにコピーすると、次のパターンが表示されます。

~/programming/sandbox $ grep export_cc\ =\ \$\{dir\}/aaa/bbb/ccc file
export_cc = ${dir}/aaa/bbb/ccc

ただし、パターンを変数やバックティックに入れると、次のような結果が得られます。

~/programming/sandbox $ grep `printf %q 'export_cc = ${dir}/aaa/bbb/ccc'` file
grep: Trailing backslash 

grepこれがなぜ違いを生み出すのか、そして引用符付き文字列を変数のパターンとして使用する方法を教えてくれる人はいますか?

答え1

問題はシェル脱出\はシェルの特殊文字ですgrep

存在する:

grep export_cc\ =\ \$\{dir\}/aaa/bbb/ccc file

export_cc\ =\ \$\{dir\}/aaa/bbb/cccexport_cc = ${dir}/aaa/bbb/cccに渡される前にシェルによって文字列として解釈されますgrep。あなたはそれを使用することができますストレス行って確認してください:

$ strace grep export_cc\ =\ \$\{dir\}/aaa/bbb/ccc file
execve("/bin/grep", ["grep", "export_cc = ${dir}/aaa/bbb/ccc",...

そしてコマンドの置き換え:

grep `printf %q 'export_cc = ${dir}/aaa/bbb/ccc'` file

二重引用符がない場合、結果は次のようになります。コマンドの置き換え以前は分割とワイルドカードシェルはexport_cc\、、、=\およびの3つの部分に分けられます\$\{dir\}/aaa/bbb/ccc。シェルはこれを3つの文字列として処理し、すべてのバックスラッシュをエスケープし、、、:grepとして渡します。export_cc\\=\\\\$\\{dir\\}/aaa/bbb/ccc

$ strace grep $(printf %q 'export_cc = ${dir}/aaa/bbb/ccc') file
execve("/bin/grep", ["grep", "export_cc\\", "=\\", "\\$\\{dir\\}/aaa/bbb/ccc",...

grepバックスラッシュexport_cc\の後に何もないパターンを受信すると、メッセージが表示されますTrailing backslash

動作するには、次のものが必要です。二重引用符コマンドの置き換え、そして使用印刷機能%s代わりに使用してください%q

$ grep "$(printf %s 'export_cc = ${dir}/aaa/bbb/ccc')" file
export_cc = ${dir}/aaa/bbb/ccc

関連情報