2

私は次の入力を持っています:

03:00.0 Ethernet controller: Broadcom Corporation NetBooty BCM5111 Gigabit Ethernet (rev 59)
03:00.1 Ethernet controller: Broadcom Corporation NetBooty BCM5111 Gigabit Ethernet (rev 59)
03:00.2 Ethernet controller: Broadcom Corporation NetBooty BCM5111 Gigabit Ethernet (rev 59)
03:00.3 Ethernet controller: Broadcom Corporation NetBooty BCM5111 Gigabit Ethernet (rev 59)
04:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
04:00.1 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
05:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
05:00.1 Ethernet controller: Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20)
06:00.0 Network controller: Intel Corporation Centrino Ultimate-N 6300 (rev 3e)                                                                                                    

これはlspciLinuxからのものであり、明らかにイーサネット/ワイヤレスデバイスとそれに対応するpciIDを示しています。この場合、出力は、システムに1つのクアッドポートBCM690 nic(私が作成した)、2つのデュアルポートBCM5709、およびIntel6300Wi-Fiコントローラーがあることを示しています。

私はそれを処理できるawkロジック(およびよりインターフェイスフルなシステムでははるかに詳細な出力)を記述して、簡潔な要約を出力しようとしています。上記の入力で与えられた提案された出力フォーマット:

4 Broadcom Corporation NetBooty BCM5111 Gigabit Ethernet (rev 59) {1x4-port}
4 Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet (rev 20) {2x2-port}  
1 Intel Corporation Centrino Ultimate-N 6300 (rev 3e)

私の限られたawkの知識で、私はこれまでほんのわずかしか成功していません。これに続いて私が得たものですがlspci -v、他のシステムからの出力を含むファイルを頻繁にレビューすることに注意してください。したがって、'/Eth|Net/{if ($2 ~ /^Eth|^Net/) print}'正しいものを確実に取得するための追加のロジックがあります。

awk '/Eth|Net/{if ($2 ~ /^Eth|^Net/) print}' lspci.txt |
awk -F: '{if ($2 ~ /^...0/) pci[$1$2]=$3; count[$3]++} END {for (i in pci) printf "%s %s\n", count[pci[i]], pci[i]}' |
uniq -c |
awk '{nic=""; for (i=3; i <=NF; i++) nic = nic $i " "; if ($1 == 1) printf "%s %s\n", $2, nic; if ($1 != 1) printf "%s %s {%dx%d-port}\n", $2, nic, $1, $2/$1}'

これにより、ほとんどの場合、目的の出力が生成されますが、ええと...単一のawkコマンドにまとめたいと思います。フィードバックをいただければ幸いです。例はさらに優れています。答えを綴る必要はありません。似たようなもののいくつかの例を指摘する必要があります。(awkよりも優れたツールを使用している場合は、私にもそのことを教えてください。)

4

1 に答える 1

3
awk '{$1 = ""; sub(" ", ""); arr[$0]++} END {for (i in arr) {print arr[i], i}}' 

最初のフィールドと最初のフィールド区切り文字を破棄します。行の残りの部分をカウンター配列へのインデックスとして使用します。最後に、カウントとインデックスを印刷します。

これは、ポート数を出力するバージョンです(複数行に分割されています)。

awk '
    {
        split($1, slot, ":");
        $1 = "";
        sub(" ", ""); 
        split($0, type, ":");
        iface[type[2]]++;
        if (!(slot[1] SUBSEP type[2] in slots)) {
            slots[slot[1], type[2]];
            slotcount[type[2]]++
        }
    }
    END {
        for (ifacetype in iface) {
            slotc = slotcount[ifacetype];
            typec = iface[ifacetype]
            ports = "";
            if (typec > 1) {
                ports = " {" slotc "x" typec/slotc "-port}"
            };
            print typec, ifacetype, ports
        }
    }'

スロット情報をアレイに保存します。最初のフィールドと最初の区切り文字を破棄します。インターフェイスを数えます。これまでにスロットを見たことがない場合は、覚えておいてください(配列要素を参照するだけでスロットが作成されます)。そのインターフェイスタイプのスロットを数えます。

インターフェイスタイプごとに、スロット数とそのタイプの数を取得します。情報を印刷します。インターフェイスごとのポート数は、タイプの数をそのタイプのインターフェイスが占有するスロットで割ったものです。

ちなみに、この二重テスト:

'/Eth|Net/{if ($2 ~ /^Eth|^Net/) print}'

次のように簡略化できます。

'$2 ~ /^Eth|^Net/ {print}'
于 2012-07-07T01:24:04.177 に答える