grep STOP 正規表現の置換 -A オプション

grep STOP 正規表現の置換 -A オプション

検索文字列を見つけた後に「|_」の特定の文字列を見つけたら、grepを停止する方法を探して/検索しています。

たとえば、「address-info:」の上の2行から始まり、「|_」行で停止する行だけを印刷し、「間に関係のない行」を印刷しないようにします。ただし、これは任意の方法で印刷できます。

入力する:

Nmap scan report for ::1.2.3.4
Host script results:
| address-info:
|   IPv4-compatible:
|_    IPv4 address: 1.2.3.4
...
irrelevant lines in between
irrelevant lines in between
irrelevant lines in between
...
Nmap scan report for ::ffff:1.2.3.4
Host script results:
| address-info:
|   IPv4-mapped:
|_    IPv4 address: 1.2.3.4
...
irrelevant lines in between
irrelevant lines in between
irrelevant lines in between
...
Nmap scan report for 2001:0:506:708:282a:3d75:fefd:fcfb
Host script results:
| address-info:
|   Teredo:
|     Server IPv4 address: 5.6.7.8
|     Client IPv4 address: 1.2.3.4
|_    UDP port: 49802

出力:

Nmap scan report for ::1.2.3.4
Host script results:
| address-info:
|   IPv4-compatible:
|_    IPv4 address: 1.2.3.4
Nmap scan report for ::ffff:1.2.3.4
Host script results:
| address-info:
|   IPv4-mapped:
|_    IPv4 address: 1.2.3.4
Nmap scan report for 2001:0:506:708:282a:3d75:fefd:fcfb
Host script results:
| address-info:
|   Teredo:
|     Server IPv4 address: 5.6.7.8
|     Client IPv4 address: 1.2.3.4
|_    UDP port: 49802

私はman grepを読み、-A -B -Cオプションを見つけました。 -Bの場合、行数を事前に知っているので大丈夫です。ただし、-A の場合、ランダムに高い値が与えられます。つまり、99999です。

grep -A99999 -B2 address-info: INPUT.txt

awkのパイプを通して「|_」を見つけます。

awk 'BEGIN {PAT=1} PAT == 1 {print $0} $1 ~ /^|_/ {PAT=0}

全体的に:

grep -A99999 -B2 address-info: INPUT.txt | awk 'BEGIN {PAT=1} PAT == 1 {print $0} $1 ~ /^|_/ {PAT=0}'

これは汎用的ではなく(99999を超える「アドレス情報:」および「|_」行の場合は動作(可能性はほとんどありませんが可能です))、CPU / MEMの非効率性、きれいではないため、本番モードでは許可されていません。

grepコマンドでこれを達成する方法を見つけたいです。

どんなアイデアがありますか?

ベストアンサー1

awk範囲で直接使用:

awk '/^Nmap scan report/;/^Host script results/,/\|_/' INPUT.txt

grep「範囲」機能はありません。しかし、パイプgrep address-info: -B2 -A 99999で処理することはできます。

おすすめ記事