web-dev-qa-db-ja.com

2つの一致するパターン間のファイルの行を印刷する

最初の行の1つのパターンで始まり、最後の行の別のパターンで終わる2つの行の間のすべての行を印刷するにはどうすればよいですか?


更新
このドキュメントがHTMLであることを言及するのは間違いだったと思います。神経に触れたようですので、忘れてください。テキストドキュメントのセクションを印刷する以外に、HTMLを解析したり、HTMLを使用したりするつもりはありません。


この例を考えてみましょう:

aaa
bbb
pattern1
aaa pattern2
bbb
ccc
pattern2
ddd
eee
pattern1
fff
ggg

ここで、行の先頭から始まるpattern1の最初のインスタンスと別の行の先頭から始まるpattern2の間のすべてを印刷したいと思います。出力にpattern1およびpattern2行を含めたいのですが、pattern2行の後には何も必要ありません。

pattern2は、セクションのいずれかの行にあります。私はそこで停止したくありませんが、^で行の開始を示すことで簡単に修正できます。

pattern1pattern2の後の別の行に表示されますが、それについてはまったく見たくありません。私は、pattern1firstインスタンスとpattern2の最初のインスタンスの間のすべてのものを探しています。

私は something を見つけました。これはsedを使用してほとんどそこに行きます:

sed -n '/^pattern1/,/^pattern2/p' inputfile.txt

...しかし、次のpattern1のインスタンスで再び印刷が開始されます

grep -n ... | cut -f1 -d:を2回使用して2つの行番号を取得し、次にtailheadを使用して必要なセクションを取得する方法を考えることができますが、もっとすっきりした方法を望んでいます。たぶんawkはこのタスクのためのより良いツールですか?

これが機能するようになったら、これをgitフックに関連付けたいと思います。その方法もまだわかりませんが、まだ読んで検索しています:)

ありがとうございました。

19
Vince

sedsed '/pattern/q'のパターンで終了させることができるため、一致が必要で、2番目のパターン一致で終了します。

sed -n '/^pattern1/,/^pattern2/p;/^pattern2/q'

これにより、最初のブロックのみが表示されます。

24
Fiximan

一般的なアプローチとして、sedを使用すると、ある一致から別の一致までの行を包括的に印刷することが簡単になります。

$ seq 1 100 > test
$ sed -n '/^12$/,/^15$/p' test
12
13
14
15

Awkを使用すると、次のように同じことができます。

$ awk '/^12$/{flag=1}/^15$/{print;flag=0}flag' test
12
13
14
15

次のように、これらを非包含にすることができます。

$ awk '/^12$/{flag=1;next}/^15$/{flag=0}flag' test
13
14

$ sed -n '/^12$/,/^15$/p' test | sed '1d;$d'
13
14
9
Will