จะพิมพ์บล็อกทั้งหมดได้อย่างไรหากมีบรรทัดเฉพาะพร้อมคำสั่ง awk

ฉันกำลังพยายามประมวลผลข้อมูลเครือข่ายจาก 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
    }

ไม่มีโชค


person rahul Kushwaha    schedule 12.03.2020    source แหล่งที่มา


คำตอบ (2)


เมื่อใดก็ตามที่คุณป้อนข้อมูลวันที่ด้วย tag(name) = การแมปค่า วิธีที่ดีที่สุดคือสร้างอาร์เรย์ก่อนเพื่อให้มีการแมปเหล่านั้น (tag2val[] ด้านล่าง) จากนั้นคุณสามารถวิเคราะห์ชุดค่าผสมของฟิลด์ที่มีอยู่และ/หรือมีค่าเฉพาะที่คุณต้องการและพิมพ์อะไรก็ได้ ฟิลด์ที่คุณต้องการตามลำดับที่คุณต้องการ ตัวอย่างเช่น:

$ 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
person Ed Morton    schedule 12.03.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 
}'
person rahul Kushwaha    schedule 12.03.2020
comment
ซึ่งจะไม่พิมพ์บันทึกสุดท้ายในอินพุตหากมี bus info และจะพิมพ์เฉพาะบางส่วนของข้อมูลหาก/เมื่อมี : (ลองนึกภาพชื่อผลิตภัณฑ์เช่น Ethernet: version 2) และจะพิมพ์บล็อกทั้งหมดจนถึงและรวมถึง อันที่มี bus info ไม่ใช่เฉพาะอันที่มีมัน - person Ed Morton; 13.03.2020
comment
ฉันคิดว่าตอนนี้จะพิมพ์แล้ว - person rahul Kushwaha; 13.03.2020
comment
อ่านส่วนสุดท้ายของความคิดเห็นของฉันอีกครั้งและคิดว่าคุณกำลังตั้งค่าไว้ที่ไหน v1=0 - person Ed Morton; 13.03.2020
comment
ฉันอัปเดตและตรวจสอบแล้ว คำสั่งนี้หากมีปัญหาใดๆ โปรดยกตัวอย่าง - person rahul Kushwaha; 14.03.2020
comment
ปัญหาเดียวที่เหลืออยู่คือจะพิมพ์ข้อมูลเพียงบางส่วนก็ต่อเมื่อ/เมื่อมี : (ลองนึกภาพชื่อผลิตภัณฑ์เช่น Ethernet: version 2) ดูวิธีที่ ฉันใช้ tag = val = $0; sub(/[[:space:]]*:.*/,"",tag); sub(/[^:]+:[[:space:]]*/,"",val) แทนที่จะใช้ฟิลด์เพื่อให้มีประสิทธิภาพโดยการแยกบรรทัดที่ : แรก แทนที่จะเป็นทุกๆ : . - person Ed Morton; 14.03.2020