回答:
これはアプリケーションによって異なります。あなたの例[では、として引数として引用する必要grepがありechoます。
シェルの場合(POSIX仕様から):
引用は、シェルに対して特定の文字または単語の特別な意味を削除するために使用されます。引用符を使用して、次の段落の特殊文字の文字通りの意味を保持し、予約語が認識されないようにし、ヒアドキュメント処理内のパラメーター展開とコマンド置換を防ぎます(ヒアドキュメントを参照)。
アプリケーションは、次の文字を引用する場合、それらを引用するものとします。
| & ; < > ( ) $ ` \ " ' <space> <tab> <newline>また、特定の状況下では、以下を引用する必要がある場合があります。つまり、これらの文字は、IEEE Std 1003.1-2001のこのボリュームの他の場所で説明されている条件に応じて、特別な場合があります。
* ? [ # ˜ = %さまざまな引用メカニズムは、エスケープ文字、単一引用符、および二重引用符です。here-documentは別の形式の引用を表します。ヒアドキュメントを参照してください。
特定のプログラム(正規表現、perl、awkを使用)には、エスケープに関する追加要件があります。
各アプリケーションには、「特殊な」文字の独自のセットがあります。あなたが遭遇した問題grepは、シェルではありませんでした。どの文字を引用符でgrep囲む必要があるかについては、「正規表現」に関するマンページのセクションをお読みください。
シェルの場合、引用符で囲む必要がある文字は次のとおりです。
;'"`#$&*?[]<>{}\
および任意の空白。
シェルによっては、他の文字も引用符で囲む必要がある場合があります。
!^%
シェルのマンページの「SHELL GRAMMAR」の下をご覧ください。
][必ずしも引用されるべきではありません。{およびへの参照が見つかりませんでした}
正規表現には複数のタイプがあり、特殊文字のセットは特定のタイプに依存します。それらのいくつかを以下に説明します。すべての場合において、特殊文字はバックスラッシュによってエスケープされます\。たとえば、代わりに[あなたが書くと一致する\[。別の方法として、文字(を除く^)は、のように角括弧で1つずつ囲むことでエスケープできます[[]。
^(サブ)式の先頭にある特別なものなど、一部のコンテキストで特別な文字は、すべてのコンテキストでエスケープできます。
他の人が書いたように:シェルでは、単一引用符で式を囲まない場合、すでにエスケープされた正規表現でシェルの特殊文字を追加でエスケープする必要があります。例:代わりに、bashのようなBourne互換シェルで(または:)と'\['書くことができますが、これは別の話です。\\["\[""\\["
grep、sed.[\*^$"$(printf '%s' "$string" | sed 's/[.[\*^$]/\\&/g')"grep -E、GNU:sed -r、* BSD:sed -E.[\(*^$)+?{|"$(printf '%s' "$string" | sed 's/[.[\*^$()+?{|]/\\&/g')"シェルは、コマンドの実行前にコマンドラインを変換する場合があります。シェルとクォートの両方をgrep使用して、一部の文字の特別な意味を削除できます。それにもかかわらず、grepシェルには異なる特殊文字があります。さらに、既存の展開の結果でなかったエスケープされていない特殊文字は、コマンドの実行前にシェルによって削除されます。
echo '[]' | grep '[]'
シェルは引数[]をに送信し、grepによって不正なブラケット式として解析されgrepます。
echo '[]' | grep \[]
上記では、同様のケースを見ることができます。バックスラッシュは削除され、[]引数としてに送信されますgrep。grep不正な形式のブラケット式を認識します。
echo '[]' | grep '\[]'
最後に、この場合、引用符はシェルによって削除され、\[]引数として送信されますgrepが、この特定の場合には¹ \[はgrepリテラルブラケットとして解釈されます。引用符は、シェルによるバックスラッシュの特殊文字としての解釈を防ぐために必要です。
¹ POSIX仕様。
bash含まれる)のあるシェルで!は、二重引用符で展開されますが、単一引用符のみが展開を停止します(またはシェルオプションをオフにします)。