1

grepについて質問があります。複数行のテキスト内で特定のパターンを探しています。多くの場合、同じ行に複数の一致があります。パターンを抽出する方法を考え出しましたが、grep は各一致を新しい行に配置します。grep がこれを行うのを止める方法はありますか? 理想的には、すべての一致を抽出し、元のファイルの行構造を保持したいと考えています。

次に例を示します。

1 つの入力行 (何千もの行があります):

MUC3A|ENST00000414964[in] MUC3A|ENST00000422757[in] MUC3A|ENST00000319509[in] MUC3A|ENST00000483133[in] RP11-395B7.2.1|ENST00000420080[me] RP11-395B7.2.1|ENST00000438198[me] RP11-395B7.2.1|ENST00000434775[5g] MUC12|ENST00000536621[5g] MUC12|ENST00000379442[5g] MUC3A|ENST00000480291[5g] 

私のgrepコマンド:

grep -oe MUC12[\|A-Za-z0-9-]*\[[A-Za-z0-9]*\]

私の現在の出力:

MUC12|ENST00000536621[5g]
MUC12|ENST00000379442[5g]

私の理想的な出力:

MUC12|ENST00000536621[5g] MUC12|ENST00000379442[5g]

何か案は?誰かが提供できる洞察に非常に感謝しています。

4

2 に答える 2

1

-oフラグを設定すると、grep各一致が新しい行に個別に出力され、この動作を変更する方法はありません。簡単な修正にはgrep、各一致の行番号を印刷してから、連続した番号の行を結合することが含まれます。これを行うために使用できますawk。このように実行します:

< file grep -one "MUC12[\|A-Za-z0-9-]*\[[A-Za-z0-9]*\]" | awk -f script.awk

内容script.awk

BEGIN {
    FS=":"
}

$1 == y {
    sub(/[^:]+:/,"")
    r = (r ? r OFS : "") $0
    next
}

x {
    print x, r
    r=""
}

{
    x=$0
    y=$1
    sub(/[^:]+:/,"",x)
}

END {
    print x, r
}

または、これがワンライナーです。

< file grep -one "MUC12[\|A-Za-z0-9-]*\[[A-Za-z0-9]*\]" | awk -F ":" '$1 == y { sub(/[^:]+:/,""); r = (r ? r OFS : "") $0; next } x { print x, r; r="" } { x=$0; y=$1; sub(/[^:]+:/,"",x) } END { print x, r }'

ここで紹介するアプローチは、でサポートされているすべての正規表現に適用できますgrep。受け入れられた答えとは異なり、このアプローチは空白で区切られていない正規表現では失敗しません-そしてそれは非常に重要かもしれません。

于 2013-02-21T15:55:02.513 に答える
1
$ awk '{
   s=""
   for (i=1;i<=NF;i++) {
      if ($i ~ /MUC12[\|A-Za-z0-9-]*\[[A-Za-z0-9]*\]/) {
         printf "%s%s",s,$i
         s=" "
      }
   }
   print ""
}' file
MUC12|ENST00000536621[5g] MUC12|ENST00000379442[5g]

RE を少し変更して式を固定し、簡潔さと移植性のために明示的な範囲の代わりに文字クラスを使用し、ゼロ (*) を許可する代わりに 1 つ以上の文字 (+) を探します。

$ awk '{
   s=""
   for (i=1;i<=NF;i++) {
      if ($i ~ /^MUC12\|[[:alnum:]-]+\[[[:alnum:]]+\]$/) {
         printf "%s%s",s,$i
         s=" "
      }
   }
   print ""
}' file
MUC12|ENST00000536621[5g] MUC12|ENST00000379442[5g]

「|」も移動しました 投稿されたサンプル入力からはそこに属していないように見えるため、文字リストの外にあります。

于 2013-02-21T13:07:11.673 に答える