一致した行の後の次の行のみを表示するにはどうすればよいですか?


218
grep -A1 'blah' logfile

「blah」が含まれているすべての行に対するこのコマンドのおかげで、「blah」を含む行の出力と、ログファイルの次の行が表示されます。それは単純なものかもしれませんが、「何とか」がある行を省略して、出力に次の行のみを表示する方法を見つけることができません。


71
多くの人が-A1オプションを探してここに来ると思います
mirelon

次に、これを使用してパブリックIPを取得します。:)curl whatismyip.org | grep -A1 'Your IP Address'
shrekuu 2015

6
同様に、-B1、-B2、-B3、-A1、-A2、-A3です。。。
meawoppl

5
@shrek curl icanhazip.com(grepは不要):)
alexyorke 2017

1
あなたの質問は私の質問に答え... -A1。ありがとう!
S3DEV

回答:


181

あなたはawkで試すことができます:

awk '/blah/{getline; print}' logfile

3
本当にgrep -A2の同等物(私が必要とするもの)を欲している人にとっては、getlineはその行を食べて次の行に進みます。だから私のために働いたのは文字通りawk '/blah/{getline; getline; print}' logfile
アーロンR.

160

grepを使い続ける場合:

grep -A1 'blah' logfile|grep -v "blah"

または

sed -n '/blah/{n;p;}' logfile

2
@ケント、先端をありがとう。しかし、私のPOVからは、grepがセッドやawkの答えは最高の答えとしてマークされた....それは多分ちょうど私です:)に比べて把握することがはるかに読みやすく、簡単です
icasimpan

2
-vの機能について知りたい場合:-v --invert-match一致の意味を反転して、一致しない行を選択します。(-vはPOSIXで指定されています。)
Sammi

2
私はこの答えが本当に好きですが、「何とか」を含む行に2行あり、2番目の行を取得したい場合は機能しません(「一致した行の次の行」だからです)。頭に浮かぶようなユースケースは考えられませんが、注目に値します。
Tin Wizard

一番上の解決策は単に「大丈夫」です。2番目の行にも "何とか"が含まれている場合は、実際に混乱しています。
riwalk

32

配管はあなたの友達です...

grep -A1一致後の次の行を表示するために使用し、結果をパイプしてtail1行のみを取得します。

cat logs/info.log | grep "term" -A1 | tail -n 1

1
「term」が最後の行にある場合、これは何も必要ではなく、何もではなく「term」を含む行を返します。
匿名の

tail -n 1はファイル全体の最後の行のみを生成します
Sebastian

13

raimからの素晴らしい回答は、私にとって非常に役に立ちました。これを拡張して、たとえばパターンの後に7行目を印刷するのは簡単です。

awk -v lines=7 '/blah/ {for(i=lines;i;--i)getline; print $0 }' logfile

9

その次の行に「何とか」が含まれない場合は、次のようにフィルタリングできます。

grep -A1 blah logfile | grep -v blah

の使用cat logfile | ...は必要ありません。


5

一般的に、あなたはここで多くのgrepを尋ねていることに同意し、別のツールがより良い解決策である可能性があることに同意します。しかし、組み込み環境では、これを実行したくない、sedまたは実行したくないawkだけかもしれません。私は次の解決策が機能することを発見しました(それらが連続した一致でない限り):

grep -A1 AT\+CSQ wvdial.out | grep -v AT\+CSQ

基本的に、それらを一致させ、一致ごとに1行のコンテキストを追加し、それを元のパターンの逆一致にパイプして、それらを取り除きます。もちろんこれは、パターンが「次の」行に表示されないと想定できることを意味します。


5

これまでのところ、この質問には多くの良い答えが出されていますが、awkを使用しないと、まだ回答がありませんgetline。以来、一般的に、それは使用する必要はありませんgetline、私はのために行くだろう。

awk ' f && NR==f+1; /blah/ {f=NR}' file  #all matches after "blah"

または

awk '/blah/ {f=NR} f && NR==f+1' file   #matches after "blah" not being also "blah"

ロジックは常に、「何とか」が見つかった行を保存してから、1行後の行を印刷することです。

テスト

サンプルファイル:

$ cat a
0
blah1
1
2
3
blah2
4
5
6
blah3
blah4
7

「何とか」の後のすべての行を取得します。これは、最初のものの後に現れる場合、別の「何とか」を印刷します。

$ awk 'f&&NR==f+1; /blah/ {f=NR}' a
1
4
blah4
7

「blah」自体が含まれていない場合は、「blah」の後にあるすべての行を取得します。

$ awk '/blah/ {f=NR} f && NR==f+1' a
1
4
7

5

これをgrepで行う方法はわかりませんが、awkを使用して同じ結果を得ることができます。

awk '/blah/ {getline;print}' < logfile

@jww違いはありません。ほんの数分間隔のタイムスタンプからわかるように、ほぼ同じ時間に回答したようです。
raimue

4

perlワンライナーアラート

ちょうど楽しみのために...試合後に1行だけ印刷する

perl -lne '$next=($.+1)if/match/;$.==$next&&print' data.txt

さらに楽しい...試合後に次の10行を印刷する

perl -lne 'push@nexts,(($.+1)..($.+10))if/match/;$.~~@nexts&&print' data.txt

コマンドが2つあるので


$。== $ nextについて説明できますか?明らかに、現在の行番号と$ nextの数値比較以上のものですが、どのように/なぜ機能するのかわかりません。
Keith Bentrup

それ以上ではありません。$. == $next && printと同じprint if $. == $next
beasy

あ、そうだ。どうも!2つの部分のうち、それぞれが真であり、ループの別々の隣接する反復で実行されます。一致した後に、順序を逆にしたい行を印刷することがポイントだったと思います(のように動作しますgrep -A1)。次の行のみを印刷し、一致する行は印刷しない場合は、この順序を維持します。(ちょうど$ nextが連続試合でどのように破壊されるかを指摘するだけです)
キース・ベントラップ

3

間違ったツールを使用しているようです。Grepはそれほど洗練されていません。仕事のツールとしてawkにステップアップしたいと思います。

awk '/blah/ { getline; print $0 }' logfile

問題が発生した場合はお知らせください。awkを少し学ぶ価値があると思います。すばらしいツールです:)

psこの例は「猫賞の無用な使用」を勝ち取りません;) http://porkmail.org/era/unix/award.html


3
ところで、印刷では「$ 0」をスキップできます。
のMichałŠrajer

0

grep / Pattern / | 尾-n 2 | 頭-n 1

最初の2番をテールし、最後の1番を先頭にして、一致後の最初の行を正確に取得します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.