一致した行と一致した行からn番目の行を出力します


18

一致した行と一致した行の4番目の行(検索対象の式を含む行)を印刷しようとしています。

私は次のコードを使用しています: sed -n 's/^[ \t]*//; /img class=\"devil_icon/,4p' input.txt

ただし、これは一致した行のみを出力します。

これは、4行目のみを印刷します。 awk 'c&&!--c;/img class=\"devil_icon/{c=4}' input.txt

一致した行と4行目のみを印刷する必要があります。


使用 egrep "pattern" -A4
バレンティンバジラミ

間にある行も出力する@ val0x00ff ..つまり、一致した行から始まる次の4行を出力します
-debal

「一致した行と、一致した行の4行目を印刷しようとしています」と言っています。grep -A 4 "pattern" file | sed -n '4p'私があなたを誤解していない限り、これはまさにあなたが望むことを行います
バレンティンバジラミ

いいえ、そうではありません。上記のコードの出力は</td>4行目ではありませんでした
-debal

回答:


18

awkでは、次のようにします

awk '/pattern/{nr[NR]; nr[NR+4]}; NR in nr' file > new_file`

または

awk '/pattern/{print; nr[NR+4]; next}; NR in nr' file > new_file`

説明

最初の解決策は、一致するすべての行を見つけますpattern。一致するものが見つかると、レコード番号(NR)を配列に格納しnrます。またNR、同じ配列の4番目のレコードも保存します。これはによって行われますnr[NR+4]NR次に、すべてのレコード()がチェックされ、nr配列内に存在するかどうかが確認されます(存在する場合)。

2番目の解決策は基本的に同じ方法で動作します。ただし、patternその行を印刷すると、その行の4番目のレコードを配列に格納nrし、次のレコードに移動します。次に、awkこの4番目のレコードNR in nrが検出されると、ブロックが実行され、その後にこの+4レコードが出力されます。

データファイルの例を次に示しますsample.txt

$ cat sample.txt 
1
2
3
4 blah
5
6
7
8
9
10 blah
11
12
13
14
15
16

最初のソリューションの使用:

$ awk '/blah/{nr[NR]; nr[NR+4]}; NR in nr' sample.txt 
4 blah
8
10 blah
14

2番目のソリューションの使用:

$ awk '/blah/{print; nr[NR+4]; next}; NR in nr' sample.txt 
4 blah
8
10 blah
14

3
いいですね、+ 1。awkここで多くのショートカットを使用していますが、簡単な説明を追加できますか(印刷がawkで暗示されている、配列が連想的であるなど)。
テルドン

@terdonに同意して、コードを少し説明してください。
デバル

@slm改善し、完全な答えを提供してくれてありがとう!
バレンティンバジラミ

1
答えてくれてありがとう、私もそれで新しいことを学んだ。
slm

4
sed -n 's/^[ \t]*/; /img class=\"devil_icon/,+4 { 3,5d ; p }' input.txt

印刷する前に、適切な行を削除するだけです{ 3,5d ; p }


あなたの式はエラーを生成します:sed: -e expression #1, char 18: unknown option to s'`-
ミネラル

4

を使用して-Aオプションを試すことができますgrep。これは、一致する行の後に印刷する行数を指定します。これをと組み合わせてsed、必要な行を取得します。

grep -A 4 pattern input.txt | sed -e '2,4d'

を使用sedして、2行目から4行目までを削除します。


3
これはpattern、ファイル内の単一の一致を想定しています。
テルドン

2

これは、Perlで任意の数の一致する行を処理できる方法です。

perl -ne '/pattern/ && do{$c=$.; print}; $.==$c+4 && print' file > new_file`

Perlで。特殊変数$.は現在の行番号です。したがって、一致する行を見つけるたびにpattern、それを印刷し、行番号をとして保存し$cます。次に、現在の行番号が以前に印刷された行番号よりも4多いときに、再度印刷します。


0
awk 'c&&!--c;/img class=\"devil_icon/{c=4};/img class=\"devil_icon/' input.txt

あなたは本質的に検索と置換を行っています。同じコマンドにfindを追加するだけで、両方が出力されます:)

awk 'c&&!--c;/pattern/{c=4};/pattern/' input.txt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.