grepが期待どおりに機能しない

grepが期待どおりに機能しない

次の内容を含む「test.log」ファイルが提供されます。

line1 Patient 123 45566
line2 Patient 432
line3 Patient 234 456
line4 Patient 321
line5

line 2次のパターンを選択して使用しようとしていますline 4

grep "Patient\s\d+\s" test.log
# but this works testing at https://rubular.com/

うまくいかず、次も行われません。

grep "Patient\s\d+\n" test.log
# but this works testing at https://regexr.com/47qd5

私は何が間違っていましたか?

ベストアンサー1

1. 名前付きクラスまたは PCRE を使用します。

GNUはgrepデフォルトでデフォルト正規表現(BRE)を使用しますが、拡張正規表現(ERE)とPerl互換正規表現(PCRE)も使用できます。

BRE と ERE はどちらもサポートされていませ\sんが、\d同様の機能があります。からman grep

最後に、以下のように、特定の名前付き文字クラスが角かっこ式内で事前定義されています。その名前は説明を必要としません。つまり[:alnum:]、、、、、、、、、、、、およびです[:alpha:]。​​​​​​​たとえば、現在のロケールの数字と文字を表す文字クラスです。 CロケールとASCII文字セットエンコーディングでは、これは同じです。 (これらのクラス名の角かっこは記号名の一部であり、角かっこ式を区切る角かっこで含める必要があります。)ほとんどのメタ文字はその文字を失います。角かっこ式内の特別な意味。テキストを含めるには、リストの最初に入れます。同様に、テキストを含めるには、始めを除く任意の場所に配置します。最後に、テキストを最後に置きます。[:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:][[:alnum:]][0-9A-Za-z]]^-

例:

$ grep -E '^[[:digit:]]+$' << 'EOF'
> foo
> 123
> bar
> EOF
123

\s以下をサポートするPCREを使用することもできます\d

$ grep -P '^\d+$' << 'EOF'
> foo
> 123
> bar
> EOF
123

2.\n動作しません

Unixではそれぞれ\nが区切りになります。ワイヤーgrep印刷ワイヤー与えられたパターンと一致します。この場合、一致\n自体は意味がありません。

$以下を使用して行末を一致させることができます。

$ grep -E 'foo bar$' << 'EOF'
> foo
> foo bar
> foo bar baz
> EOF
foo bar

または、 -z/--null-dataオプションを渡して「複数行」モードを有効にします(必要なものと正確に一致するには、いくつかの追加の解決策が必要です)。

$ grep -Poz '(?<=\n)?foo bar\n' << 'EOF'
> foo
> foo bar
> foo bar baz
> EOF
foo bar

3. 最初の例はあなたの考えに合わない。

最後のものはandの代わりにandと\s一致します:line 1line 3line 2line 4

$ grep -P 'Patient\s\d+\s' << 'EOF'
> line1 Patient 123 45566
> line2 Patient 432
> line3 Patient 234 456
> line4 Patient 321
> line5
> EOF
line1 Patient 123 45566
line3 Patient 234 456

おすすめ記事