
なぜ
grep e\\.g\\. <<< "this is an e.g. wow"
そして
grep e\.g\. <<< "this is an e.g. wow"
同じことをしますか?
3番目のスラッシュを追加すると、同じ結果が得られます。しかし、4番目のスラッシュを追加するとすぐには機能しません。これは以前のコース試験の問題に関連しています。 2つのバックスラッシュがある項目に「eg」として行を出力できるかどうかを尋ねます。最初はうまくいかないと思いましたが、うまくいくかどうかを確認しようとしました。説明は何ですか?
答え1
まず、単一のスラッシュ一致が多すぎます。
$ echo $'eegg \n e.g.' | grep e\.g\.
eegg
e.g.
ハン吹くこれに関する逃避期間は刑期間と同じです。 Bashは次に期間を渡します。grep。 grepの場合、ピリオドは何でも一致できます。
それでは、次の点を考えてみましょう。
$ echo $'eegg \n e.g.' | grep e\\.g\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\\.g\\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\\\.g\\\\.
$
Bashは二重スラッシュを見つけたら、それを単一のスラッシュに減らしてgrepに渡します。上記の3つのテストの最初のものでは、予想どおりにピリオドの前に単一のスラッシュが表示されます。したがって、これが正しいことです。
トリプルスラッシュを使用すると、Bashは最初の2つのスラッシュを単一のスラッシュに減らします。それからそれを見た\.
。エスケープされたピリオドは Bash に特別な意味がないため、通常のピリオドに簡略化されます。その結果、私たちが望むように、grepはピリオドの前にスラッシュを見ます。
4つのスラッシュを使用すると、Bashは各スラッシュのペアを単一のスラッシュに減らします。 Bashはgrepに2つのスラッシュとピリオドを渡します。 grepは2つのスラッシュと1つのピリオドを見て、2つのスラッシュを単一のスラッシュに減らします。言葉減らす入力にスラッシュの後に文字がない場合、一致するものはありません。
最後に、一重引用符内のすべての文字はリテラルであることを覚えておいてください。したがって、次の3つの入力行がある場合、grepコマンドは入力にリテラルスラッシュがある行のみを一致させます。
$ echo 'eegg
e.g.
e\.g\.' | grep e\\\\.g\\\\.
e\.g\.
Bash 動作の概要
Bashの場合、ルールは次のとおりです。
2つのスラッシュが1つのスラッシュに減ります。
一般文字(ピリオドなど) 前のスラッシュは一般文字(ピリオド)のみです。
したがって:
$ echo \. \\. \\\. \\\\.
. \. \. \\.
これらすべての混乱を避ける簡単な方法があります。 Bashコマンドラインでは、正規表現は一重引用符で囲む必要があります。一重引用符内で、Bashはすべてを保持します。
$ echo '\. \\. \\\. \\\\.' # Note single-quotes
\. \\. \\\. \\\\.
答え2
文字列に対してのみ出力は同じですが、通常、これらの正規表現は他の操作を実行します。例を少し変更して、2番目のパターンe,g,
(カンマを含む)、3番目のパターンe\.g\.
(ドット)、4番目のパターンe\,g\,
(カンマ)、および-o
一致する部分のみを印刷するgrepオプションを追加します。
以下の場合は、
.
すべての文字と一致します(''
周辺環境を参照してくださいe.g.
。これについては後で説明します)。$ grep -o 'e.g.' <<< grep -o 'e.g.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,' e.g. e,g,
次に、
.
バックスラッシュエスケープを使用して\
リテラルのみを.
一致させます。$ grep -o 'e\.g\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,' e.g.
ただし、リテラルが次の(つまりすべての文字)に一致するように
\
別のエスケープを使用できます。\
\
.
$ grep -o 'e\\.g\\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,' e\.g\. e\,g\,
\.
しかし、単に矛盾が\,
必要な場合は、点\
の特別な意味を逸脱するために別のものが必要です。$ grep -o 'e\\\.g\\\.' <<< 'this is an e.g. e,g, e\.g\. e\,g\,' e\.g\.
around grep パラメータを使用しないため、''
シェル解析でバックスラッシュをエスケープするには、別のバックスラッシュを追加する必要があります。
grep 'e\.g\.' => grep e\\.g\\.
grep 'e\\.g\\.' => grep e\\\\.g\\\\. (each backslash has to be quoted separately)
grep 'e\\\.g\\\.' => grep e\\\\\\.g\\\\\\. (3 x 2 = 6 backslashes in total)
答え3
を実行すると、grep e\.g\.
シェルはバックスラッシュを使用するため、grep e.g.
一致するものを実行します。を実行すると、grep e\\.g\\.
シェルはスラッシュを再利用し、aを実行するとgrep e\.\g.
再び一致します。これでシェルのバックスラッシュは同じです\\
。したがって、がある場合、最初は\\
エスケープシーケンス、2番目はリテラルバックスラッシュです。あなたがaをするときにリテラルにするgrep e\\\.g\\\.
最初の文字の前にエスケープシーケンス()がないので、それでも終了します。grep e\.\g.
\はバックスラッシュなので、最終的には明らかに一致しません。\
\
\
grep e\\\\.\\\\g
grep e\\.g\\.
シェルが何をしているのかを見るには、echoを使用してください(例:echo grep e\\.g\\. <<< "this is an e.g. wow"
vs echo grep e\\\\.g\\\\. <<< "this is an e.g. wow"
.)。
答え4
これら2つのコマンドは入力に対してのみ同じ出力を生成しますが、異なる点で異なります。何が起こっているのかを理解するには、まずパラメータがどのように解釈されるのか、bash
それからどのように解釈されるのかを知る必要がありますgrep
。
バッシュから脱出
\
\
後続の文字(自分を含む)の特別な意味を取り消す特殊文字です。次の文字に特別な意味がない場合は、変更せずに渡されます。コマンドと結果の例:
echo \a
:a
— エスケープされた一般文字は文字を提供します。echo \\
:\
— 特殊文字エスケープは文字を提供します。echo \\\a
:\a
——特別さと普通さの組み合わせecho \\\\
:\\
— 組み合わせ特別、特別
echo
bash
結果の文字列は、解釈後に印刷されます。追加情報:バッシュ文書、バッシュハッカーウィキ、POSIX仕様。
.
特別な意味はありませんbash
。シェルの一般的な文字です。あなたの例に関連する順序は次のとおりです。
echo .
:.
echo \.
:.
echo \\.
:\.
echo \\\.
:\.
echo \\\\.
:\\.
Bashの中国語テキスト文字列に対するより簡単な解決策
パラメータを文字通り渡すには、bash
単一引用符エスケープを使用します'
。一重引用符の間では、一重引用符のみが特別な意味を持つ文字であるため、文字の特別な意味を気にする必要はありません。文字列の最初の部分を囲んだ後に単一引用符を挿入できます。例:
echo 'part1'\''part2'
: part1'part2
grepの正規表現
\
はエスケープ文字で、その意味はと似ていますbash
。.
特殊文字すべての文字の発生を示します。。望むより:POSIX正規表現、GNU grep正規表現。正規表現の例:
.
a
- またはなどのすべての文字と一致します。.
\.
—.
リテラル一致のみ可能
あなたの模範
以下の各例の2行目では、'
どのリテラル文字列が渡されるかを示すbash
単一引用符付きの対応する項目を見つけることができますgrep
。その後、grep
エスケープを実行した後の例で可能な唯一の特殊文字は、.
任意の文字と一致することです。 3行目は、式が一致する項目の説明です。
grep e.g. <<< "this is an e.g. wow"
grep 'e.g.' <<< "this is an e.g. wow"
e
すべての文字g
すべての文字—一致e.g.
などの文字列良いeagb
grep e\.g\. <<< "this is an e.g. wow"
grep 'e.g.' <<< "this is an e.g. wow"
e
すべての文字g
すべての文字—一致e.g.
などの文字列良いexgy
grep e\\.g\\. <<< "this is an e.g. wow"
grep 'e\.g\.' <<< "this is an e.g. wow"
e.g.
文字通り -e.g.
一致のみgrep e\\\.g\\\. <<< "this is an e.g. wow"
grep 'e\.g\.' <<< "this is an e.g. wow"
e.g.
文字通り -e.g.
一致のみgrep e\\\\.g\\\\. <<< "this is an e.g. wow"
grep 'e\\.g\\.' <<< "this is an e.g. wow"
e\
すべての文字g\
すべての文字—矛盾e.g.