web-dev-qa-db-ja.com

grepの「+」の問題

大きなテキストファイルで次のような行を見つけるためにgrepコマンドを作成しようとしています。

<div class="node_thumbnail" data-type="file" name="GOPR0036.MP4_frame000001.jpg" data="813334c25191468c9f1c57afc99fde60" aid="133948" rel="/Files/ToolTipView?fileId=813334c25191468c9f1c57afc99fde60&pageNo=1&NoCache=101016083044" rev="topMiddle">

しかし、+シンボルは、以下のコマンドで問題を引き起こしているようです:

 grep 'data=[a-z,0-9,\"]' file

たくさんのヒット

 grep 'data=[a-z,0-9,\"]+' file

ヒットなし

7
Martin KS

+に「1つまたは複数の先行するアトム」を意味させる場合は、次のいずれかを実行する必要があります。

  1. -E(拡張正規表現)(または-P、PCRE)を使用します。

    grep -E 'data=[a-z,0-9,\"]+' file
    
  2. +をエスケープすると、grepでデフォルトで使用される基本正規表現で特別に処理されます。

    grep 'data=[a-z,0-9,"]\+' file
    
14
muru

ポイント:

  • +はERE(Extended Regular Expression)トークンであり、grep-Eオプションが使用されている場合、またはBRE(Basic Regex)の場合にエスケープされた(\+がある場合にのみ使用できます。レギュラーgrep

  • 文字クラス[a-z,0-9,\"]は、[a-z][0-9],、または"の間の文字のいずれかに一致します。これはあなたが望むものではないかもしれません

  • 通常、grepは行全体を出力します。一致した部分のみを出力する場合は、grep-oオプションを使用します


例に基づいて、次のことができます。

grep -E '\bdata=[a-z0-9"]+\b' file
  • -EはEREを有効にします
  • \bは文字列のエッジと一致し、幅はゼロです
  • data=は、data=と文字通り一致します
  • [a-z0-9"]は、[a-z][0-9]、および"の任意の文字に一致します。 +は前のトークンと1回以上一致します

\bを使用せずに現在のパターンを修正しても、foo fdata=2322abdata=12ABなどの誤検知に一致します。

例:

% grep -oE '\bdata=[a-z0-9"]+\b' <<<'<div class="node_thumbnail" data-type="file" name="GOPR0036.MP4_frame000001.jpg" data="813334c25191468c9f1c57afc99fde60" aid="133948" rel="/Files/ToolTipView?fileId=813334c25191468c9f1c57afc99fde60&pageNo=1&NoCache=101016083044" rev="topMiddle"'
data="813334c25191468c9f1c57afc99fde60
9
heemayl