59083


bashで正規表現の検索パターンとして`$`記号を指定したいのですが、エスケープが必要ということは理解しているのですがエスケープはバックスラッシュを直前に1つ入れると理解しているのですが、この場合`\$`ではうまくいかず`\\$`のようにバックスラッシュを2つ差し込むとうまく動くのですがなぜ1つではダメなのでしょうか？

[code]

    export GREP_OPTIONS='--color=always'
    
    echo I love $ | grep \\$
    I love $
    
    echo I love $ | grep \$
    I love $
    
[/code]

上記のコードでは色付けされていませんが、手元のbashではバックスラッシュを2ついれると`$`記号が赤字で出力されるのですが、1つだと黒字で出力されています。

初歩的な質問で申し訳ありませんが、回答よろしくお願いします。

マルチポスト <https://teratail.com/questions/211988>


CC BY-SA 4.0
2019-09-15T11:57:46.540
59082
2019-09-15T21:20:12.557
2019-09-15T13:05:39.727
35832
35832
question
macos bash 正規表現 grep
grepの引数として$記号を渡す際のエスケープについて


質問冒頭

> bashで正規表現

という表現がそもそもの問題がどこにあるかを正しく理解できていないことを示しています。bashももちろん正規表現を扱うことがありますが、今回は無関係です。

* * *

今回、bashはgrepという外部プログラムを起動するだけです。

grepとしても`$`は行末を表すメタ文字ですので、この機能をキャンセルするためには`\`でエスケープする必要があります。つまりgrepが受け取るべき引数文字列は`\$`です。  
次にbashにおいて、`\`はエスケープ記号、`$`は変数の接頭辞とどちらも特殊な機能を持つためそれぞれ`\`でエスケープする必要があります。つまりbashに入力すべき文字列は`grep
\\\$`となります。

この手のエスケープをエスケープしてわけがわからなくなることを[傾斜爪楊枝症候群](https://en.wikipedia.org/wiki/Leaning_toothpick_syndrome)と呼ばれています。

* * *

> grep \$
> とバックスラッシュが2つでも同様の出力結果が得られ、書籍ではそのように記述されているのですが同様の結果が得られるのはどういう解釈をすれば理解できるのでしょうか？

「バックスラッシュを2ついれると$記号が赤字で出力される」とあるように異常状態を示しています。先に説明したとおり、bashにとって`$`は変数の接頭辞なため、`$`の後ろには変数名が続くべきです。それがないため赤字で警告しています。  
バックスラッシュ２つは正しくはありませんが、bashは変数としての解釈を諦め`$`をそのままgrepに渡すため、結果として`grep \\$`は`grep
\\\$`と同じとなります。  
もし書籍にそのような記述がなされているのであれば、筆者の知識が浅いのか、このような説明を端折ったかのどちらかで、どちらであってもろくな書籍とは言えないような気がします。

> echoコマンドに関しては $ を出力したい時に引数に echo \$ とバックスラッシュ1つで意図通りの出力結果が得られますが、この場合も echo
> \\\$ と記述しなくてよいのはなぜでしょうか？ grepコマンドに引数として渡す場合とでバックスラッシュの記述の仕方が変わるのはなぜなのでしょうか？

**bash、echo、grepとそれぞれ立場の異なる３つのプログラムに分けて解釈する必要があります。**  
grepは正規表現として`$`を特別視します。しかしechoは`$`を特別視しません。ですからechoが受け取るべき引数文字列は`$`となります。次にbashにおいて、`$`は変数の接頭辞と特殊な機能を持つため`\`でエスケープする必要があります。つまりbashに入力すべき文字列は`echo
\$`となります。


CC BY-SA 4.0
2019-09-15T12:28:54.343
59083
2019-09-15T21:20:12.557
2019-09-15T21:20:12.557
4236
4236
59082
answer