エスケープパターンの入力に問題があります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/ccc
export_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