2016-10-17 1 views
4

私はこのようなことをしたい。私は多くのオレンジ、リンゴやブドウがStart-patternEnd-patternのそれぞれの間にあるか印刷したい。ここどのようにsedを使って2つのパターン間の線を抽出し、それをループで後処理することができますか?

Start-pattern 
orange 
apple 
grape 
orange 
orange 
End-pattern 
####### 
bla bla bla 
######## 
Start-pattern 
orange 
apple 
grape 
apple 
orange 
End-pattern 
####### 
bla bla bla 
######## 
Start-pattern 
orange 
orange 
orange 
End-pattern 
####### 
bla bla bla 
######## 

:私は下のテキストを持っていると言います。

上記の例では、最初の開始パターンと終了パターンの間に3つの「オレンジ」、1つの「リンゴ」と1つの「ブドウ」があります。 2番目のSPとEPで2 "オレンジ"、2 "リンゴ"と1 "ブドウ"。

貴重な回答を待っています。

+1

明確にするために、質問に完全な期待出力を追加できますか? – Sundeep

答えて

3

あなたはこのawk試すことができます:我々は、このコードのawk 3のようにブロックを分割することができます

awk '$1 ~ /^Start-pattern$/{p=1;next} $1 ~ /^End-pattern$/{p=0; for (var in a) {print var,a[var];a[var]=""}; print "######"; next} p{a[$1]++}' file 

より読みawk

$1 ~ /^Start-pattern$/ { 
    p=1; 
    next 
} 
$1 ~ /^End-pattern$/ { 
    p=0; 
    for (var in a) { 
     print var,a[var]; 
     a[var]="" 
    } 
    print "######"; 
    next 
} 
p { 
    a[$1]++; 
} 

説明。

  1. Start-patternパターンを確認してから、p=1を有効にします。
  2. End-patternパターンを確認し、p=0を無効にします。その後、対応するカウントでa[]を印刷します。
  3. これは、これら2つのパターンの間の各アイテムの出現回数を連想配列に格納します。
+0

ありがとうございます。私はこれを試してみる。どのように動作するのか教えていただけますか?非常に役立つだろう –

1

これはあなたのために働くかもしれない(GNU sedは、ソートとuniqの、エコー):SEDS上

sed -nr '/Start/,/End/!b;/Start/h;//!H;/End/!b;x;s/^[^\n]*\n(.*)\n.*/echo "\1"|sort|uniq -c/e;s/\n//g;p' file 

電源を入れ-nと自然のようにgrepします。ホールドスペース(HS)にStartEndの間の行を格納し、End文字列に遭遇したら、HSからパターンスペース(PS)を置き換えます。開始および終了ヘッダー/フッターを削除し、置換コマンドのevaluateフラグを使用します。囲まれた行をソートにエコーし、uniqコマンドを使用して一意の行を数えます。改行をすべて削除し、PSの内容を印刷します。

関連する問題