検索文字列を見つけた後に「|_」の特定の文字列を見つけたら、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
で処理することはできます。
答え2
grep
目的の行の先頭を一致させるには(他の行との不一致テスト):
grep -E '^(Nmap scan report for|Host script results:|\|[ _])' INPUT.txt
またはsed
範囲パターン(例:奇妙なソリューション)
sed -n '/^Nmap scan report for/,/^|_/p' INPUT.txt
- スタート:
^Nmap scan report for
- 終わり:
^|_