bashで正規表現の検索パターンとして$記号を指定したいのですが、エスケープが必要ということは理解しているのですがエスケープはバックスラッシュを直前に1つ入れると理解しているのですが、この場合$ではうまくいかず$のようにバックスラッシュを2つ差し込むとうまく動くのですがなぜ1つではダメなのでしょうか?
macOS
1export GREP_OPTIONS='--color=always' 2echo I love $ | grep \$ 3I love $ 4echo I love $ | grep $ 5I love $ 6
上記のコードでは表現しづらいでが、手元のbashではバックスラッシュを2ついれると$記号が赤字で出力されるのですが、1つだと黒字で出力されています。
初歩的な質問で申し訳ありませんが、回答よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/16 01:59 編集
回答2件
0
ベストアンサー
$
はbashでは環境変数の展開に使われる$
の後の文字が空白文字だったり行末だったりで展開することがなければ$
のままになる- bashで
$
の変数展開をやめさせければ\
でクォートする - bashで
\
によるクォートをやめさせたければ\
とする - 正規表現で
$
は行末に長さ0でマッチする - '$'という文字にマッチさせる正規表現は
$
plain
1export GREP_OPTIONS='--color=always' 2C=love
環境変数Cをセットしておきましょう。
plain
1echo I love C$C | grep $C
の結果は
I love Clove
です。(強調表示部分がカラー表示です。以下同様)
$Cが文字列ioveに展開されているのが分かりますね。echo I love Clove | grep love
を実行したのと同じことなのです。
質問で
plain
1echo I love $
するとI love $
が出るのは"$の後続がアルファベットじゃないから環境変数として正しくない"ため$自身がでています。
環境変数の展開を明示的に止めたい時はどうするかというと、\
でエスケープします。
plain
1echo I love C$S | grep $
とすると結果は
I love C$S
です。強調表示がありません。
にも関わらずI love C$Sが表示されていることに気をつけてください。(echo hoge | grep huga
では結果が出ないことを確認してください)
ということはこの行はマッチしているのです。
$
が行末にマッチする正規表現なので、行末に長さ0でマッチしているのです。
だからマッチしていてかつ強調表示がないという結果になるのです。
plain
1echo I love C$C | grep e$
すると結果は
I love Clove
です。
e$
が "eの直後に行末" という意味になるので行末のeにしかマッチしていないことを確認してください。
plain
1echo I love C$C | grep e
の結果が
I love Clove
なのと見比べてください。
正規表現で$
という文字自身を検索したい時は$
という正規表現を渡さなければなりません。
bashで$
と書くと\
記号の作用で変数展開をやめて$
という文字自身になります。
\
は渡りません。
\
を渡したければ\
と書きます。
plain
1echo $C
の結果が
$C
で($の変数展開する機能が\で抑止されている)
plain
1echo \$C
の結果が
\love
で(\の「$の変数展開を抑止する機能」がもう1つの\で抑止されている。$は変数展開の機能を持つ)
plain
1echo \$C
の結果が
$C
なことを確認してください。
(\の「$の変数展開を抑止する機能」がもう1つの\で抑止されている。$の変数展開する機能が\で抑止されている)
以上から質問でやりたいことをキッチリ書くなら
plain
1echo I love $ | grep \$
とします。
こうするとechoはI love $
という文字列を出力して、grepは第1引数に$
を取ります。
これで文字列中の$
にマッチして
I love $
という結果を得ます。
投稿2019/09/15 13:56
編集2019/09/15 15:26総合スコア11231
0
Bashが、引数の\$
を$
にしてそれをgrep
に渡します。
シェルの特殊文字(空白文字、|
>
<
&
など)自体をプログラムに渡したいときは、バックスラッシュを前置するか引用符で囲みます。
例:1つの空白をコマンドに渡したい場合
sh
1grep \ 2grep ' ' 3grep " "
$
自体もシェルの特殊文字なので、\$
と書かないといけないケースもあります。
例:$A
をプログラムに渡したい場合
sh
1grep \$A ⇒ NG ($Aが変数展開される) 2grep \$A ⇒ OK
投稿2019/09/15 09:01
総合スコア85886
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/15 09:45
2019/09/15 10:26
2019/09/15 11:04
2019/09/15 15:14 編集
2019/09/16 03:05
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。