AWK は、特定の文字列の抽出中に出力ラインを接続します。

AWK は、特定の文字列の抽出中に出力ラインを接続します。

サブネットへのnmapの出力を考慮すると

Nmap scan report for 192.168.1.20
Host is up (0.010s latency).
MAC Address: EC:13:B2:E2:20:48 (Netonix)
Nmap scan report for 192.168.1.21
Host is up (0.010s latency).
MAC Address: EC:13:B2:E2:13:68 (Netonix)
Nmap scan report for 192.168.1.23
Host is up (0.010s latency).
MAC Address: EC:13:B2:E1:AE:A8 (Netonix)
Nmap scan report for 192.168.1.99
Host is up (0.00076s latency).
MAC Address: 90:6C:AC:48:86:DA (Fortinet)

目的はcsvまたは他の区切り形式で出力を取得することです。

IP,MAC,RTT
192.168.1.20,EC:13:B2:E2:20:48,0.010s
192.168.1.21,EC:13:B2:E2:13:68,0.010s
...

上記の作業は、AWKを使用して2段階プロセスで行われました。

$time_date=$(date "+%Y-%m-%d_%T")    # Get the immediate date and time
$nmap_command=$(nmap -sP 192.168.1.0/24 -n --max-rtt-timeout 50ms)

# Concatenate all lines including and between the patterns "Nmap scan report for"
c_list=$((awk '/Starting|done:/ {next} /Nmap scan report for/{ if (x) print x; x=""; }{ x=(!x)?$0:x" "$0; }END{ print x; }')<<<$nmap_command)

# Extract the values of interest from each line, add a header line, then add delimiter for every value extracted
list=$((awk -v OFS=',' -v date=$time_date 'BEGIN{ print "Date,IP,MAC,RTT" };{ gsub(/[()]/,""); for (I=1;I<=NF;I++) if ($I == "for") ip=$(I+1); else if ($I == "up") lat=$(I+1); else if ($I == "Address:") mac=$(I+1); } { print date, ip, mac, lat }')<<<$c_list)

printf '%s\n' "$list" > ~/Desktop/list.csv  # Send output to file

exit 0

問題は 上記の2段階のawkプロセスを1つのawkコマンドに結合できますか?事前に提供していただいたすべての情報に感謝します。

編集する いくつかのバリエーションでこの2つのステップを強化してください。

x_list=$((awk '/Starting|done:/ {next} /Nmap scan report for/{ if (x) print x; x=""; }{ x=(!x)?$0:x" "$0; }END I=x BEGIN{ print "Date,IP,MAC,RTT" };{ gsub(/[()]/,""); for (I=1;I<=NF;I++) if ($I == "for") ip=$(I+1); else if ($I == "up") lat=$(I+1); else if ($I == "Address:") mac=$(I+1); } { print date, ip, mac, lat }')<<<$list_ips)

景色は明るくありません。 AWK は、常に END と BEGIN の間隔で処理を停止する妥当な理由を提供します。この演習は、実際にすべてのデータを繰り返しパターンでレンダリングできる(bash)関数を生成しようとし、nmap出力は単なる例です。

答え1

一般的なアプローチは、すべての行の必須情報をawk変数に保存し、ブロックの最後の行からデータを印刷することです。したがって、たとえば、次のようなものがあります(例データには表示されないため、ホスト出口遅延ケースをコーディングしていません)。

nmap -sP 192.168.1.0/24 -n --max-rtt-timeout 50ms |
  awk '/Nmap scan report for / {ip=$5}
       /Host is up/ { latency=$4 ; sub(/(/,"",latency) }
       /MAC Address: / { mac=$3; print(ip "," mac "," latency) ; ip=mac=latency="unknown" }
       BEGIN { print "IP,MAC,RTT"}

データが常に完全であるかどうかに応じて、ブロックの最後の行から変数を消去する必要がある場合と必要がない場合があります。多くの変数がある場合は、ipスカラー変数の代わりに配列を使用することをお勧めします。これは、1回の削除ですべて消去できるためmacです。latency

関連情報