sed - 2番目のモードでテキストブロックを印刷する方法は?

sed - 2番目のモードでテキストブロックを印刷する方法は?

2つのテーブルを含むHTMLページがあります。

両方のテーブルは同じラベル " <table role="grid">"で始まり、2番目のテーブルコードを表示したいと思います。

現在は最初の項目だけを表示することがわかっています。

sed -n '/<table role=\"grid\">/,/<\/table>/p' page.html

あなたは何をしますか?

答え1

これはうまくいきますが、より簡単な解決策が必要だと確信しています。

sed -n '/<table role=\"grid\">/{
 x
 /^$/b
 x
:loop
 p
 /<\/table>/q
 n
 b loop
}'

一致すると、table行が予約済みスペースに変わり(x)、以前に予約されたコンテンツが比較されます。最初は空なので(/^$/)、スクリプトの最後に分岐します(b)。次回は予約は空ではありません(最初のテーブル行があります)。したがって、スワップ(x)を元に戻し、終了(q)時にテーブルの終わりが一致するまで行(p)を印刷するループを開始します。毎回次の行(n)が得られ、ループラベルに再分岐します。

awkでははるかに簡単です。

awk '/<table role=\"grid\">/,/<\/table>/ { if(n==1)print }
     /<\/table>/ { n++ }'

答え2

私は以下を使用しますperl

perl -ne 'if(/<table role="grid">/){$i++;$k=1} 
          if($i==2 && $k==1){print} 
          if(/<\/table>/){$k=0;}' file

説明する

  • perl -ne: 入力ファイルを 1 行ずつ読み込み、与えられたスクリプトを-e各行に適用します。
  • if(/<table role="grid">/){$i++;$k=1}:行が一致したら、<table role="grid">値に1を加えて1に$i設定します。$k
  • if($i==2 && $k==1){print}:現在の値が$i2で現在の値が$k1の場合(したがってa<table role="grid">とaの間にあり、</table>今回が2番目の場合<table role="grid">)、現在の行を印刷します。
  • if(/<\/table>/){$k=0;}$kこの行が一致すると0にリセットされます</table>

関連情報