私のgrep式でタブ文字と一致させるために$ 'string'を使用する必要があるのはなぜですか?

私のgrep式でタブ文字と一致させるために$ 'string'を使用する必要があるのはなぜですか?

このコードを使用する場合:

echo -e '\t\t\tString' | grep '^[\t]*String'

一致しないため、結果は空ですが、次のようになります。

echo -e '\t\t\tString' | grep $'^[\t]*String'

働く私はスクリプトとターミナルでコードの最初の行を100回以上使ったことがあります。最近変わった点はありますか? 「$」文字が必要なのはなぜですか?それとも私が何か間違っているのでしょうか?

答え1

ANSI-Cの引用

Bashのマニュアルによると、これは次のようになります。ANSI-Cの引用。このマニュアルには次のように記載されています。

言葉を形成する$ '文字列'特別待遇を受けてください。ワードは、ANSI C規格で指定されているように置き換えられたバックスラッシュエスケープ文字を使用して文字列に展開されます。

実際、これは'\t'タブには展開されませんが、$'\t'拡張されることを意味します。出力は using と同じでなければなりませecho -eんが、文字列が使用されるどこでも使用できます。コマンドの置き換え

GNU sedなどのユーティリティは独自のエスケープ文字拡張を実行しますが、GNU grepはそうではありません。 Bashシェル(grepではない)は、ANSI-C引用符付き文字列からエスケープ文字を拡張します。 ANSI-C引用符がない場合、公開した正規表現に入力に一致するタブ文字は含まれません。

答え2

正規表現には単一の型がないことに注意してください。少なくとも、basic regular expressionsまたはBRE(時々のみRE)、extended regular expressionsまたはおよびEREまたはperl compatible regular expressionsありますPCRE。これらの言語はすべてわずかに異なる構文を使用します。現在のバージョンはGNU grep3つすべてをサポートし、BREデフォルトです。オプションとforオプションをERE使用する必要があるためです。あなたの例は基本と拡張REでのみ動作し、バックスラッシュは意味を失い、バックスラッシュまたは文字tと一致します。デフォルトでは、サポートされている他の言語でこのモードを使用している可能性があります。これは最も強力なバージョンなので意味があります。またはあなたはどこかにいるかもしれません。-EPCRE -P-P[\t]PCREalias grep='grep -P'

答え3

.が省略された場合、最初の行は有効です^。うまくいくかもしれませんが、想像していた方法ではないかもしれませんか?私はgrepその行動が重要な時点で変わったと思います。

echoエスケープシーケンスはデフォルトでは翻訳されません。あなたは-eこれが必要です。シェルに似ています。$'...'シェルにエスケープシーケンスを使用させる必要があります。

関連情報