Как напечатать весь блок, если он содержит определенную строку с командой awk? - PullRequest
1 голос
/ 12 марта 2020

Я пытаюсь обработать сетевую информацию из lshw -c network с помощью команды awk

, вывод выглядит так: -

*-network:3
   description: Ethernet interface
   product: I350 Gigabit Network Connection
   vendor: Intel Corporation
   physical id: 0.3
   bus info: pci@0000:03:00.3
   logical name: eth1
   version: 01
   serial: xx:xx:xx:xx:xx:xx
   size: 1GB/s
   capacity: 1GB/s
   width: 32 bits
   clock: 33MHz
*-network                 
   description: Ethernet interface
   physical id: 1
   logical name: eth0
   serial: yy:yy:yy:yy:yy:yy
   capabilities: ethernet physical
   configuration: broadcast=yes driver=vif link=yes multicast=yes

Я хочу напечатать это в табличном формате, но только если блок содержит bus info:, здесь только 1-й является квалифицированным блоком и будет напечатан в формате

конечный вывод: -

description   product   vendor   physical id   bus info ...
Ethernet..    I350 G..  Intel..  0.3           pci@0000:03:00.3

мое лучшее усилие: -

    lshw -c network | 
    awk -v FS=: 
    $0 ~ /*-network.*/ {
        v1 = NR; 
        v2 = ""; 
        v3 = 0
    } 

    NR > v1 && v3 == 0 {
        v2 = v2"@"$3
        } 

    $1 ~ /bus info.*/ {
        v3 = 1
        }  

    v3 == 1 {
        split(v2, ar, "@"); 
        for (t in ar) { print t}; 
        print $1
    }

без удачи

Ответы [ 2 ]

1 голос
/ 12 марта 2020

Всякий раз, когда у вас есть дата ввода с тегами (name) = сопоставления значений, лучше сначала создать массив, содержащий эти сопоставления (tag2val[] ниже), а затем вы можете анализировать любые комбинации полей, присутствующих и / или имеющих указанные c значений, которые вам нравятся, и печатайте все поля, которые вам нравятся, в любом порядке. Например:

$ cat tst.awk
BEGIN { OFS="\t" }
/^[*]/ { prt() }
{
    gsub(/^[[:space:]]+|[[:space:]]+$/,"")
    gsub(OFS," ")
    tag = val = $0
    sub(/[[:space:]]*:.*/,"",tag)
    sub(/[^:]+:[[:space:]]*/,"",val)
    tag2val[tag] = val
}
END { prt() }

function prt(   flds, numFlds, fldNr) {
    numFlds = split("description,product,vendor,physical id,bus info",flds,/,/)
    if ( "bus info" in tag2val ) {
        if ( !doneHdr++ ) {
            for (fldNr=1; fldNr<=numFlds; fldNr++) {
                tag = flds[fldNr]
                printf "%s%s", tag, (fldNr<numFlds ? OFS : ORS)
            }
        }
        for (fldNr=1; fldNr<=numFlds; fldNr++) {
            tag = flds[fldNr]
            val = tag2val[tag]
            printf "%s%s", val, (fldNr<numFlds ? OFS : ORS)
        }
    }
    delete tag2val
}

.

$ awk -f tst.awk file | column -s$'\t' -t
description         product                          vendor             physical id  bus info
Ethernet interface  I350 Gigabit Network Connection  Intel Corporation  0.3          pci@0000:03:00.3
0 голосов
/ 12 марта 2020

Если кому-то интересно:

Эта команда работает: -

lshw -c network | 
awk -v out='description\tproduct\tvendor\tphysical id\tbus info\tlogical name\tversion\tserial\twidth\tclock\tcapabilities\tconfiguration\tresources' 
    -v v1=0 -F ': ' 
' $0 ~ /*-network.*/ {
    if (v1 == 1) {print out;} 
    out = ""; 
    v1=0 
} 
$1 ~ /bus info.*/ { 
    v1 = 1
    } 
{ 
    out = out"\t"$2 
} 
END{ 
    if (v1 == 1) print out 
}'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...