2016-06-03 10 views
5

ho il seguente testo ...Awk impostare la variabile per la linea dopo se partita dichiarazione

BIOS Information 
Manufacturer    : Dell Inc. 
Version     : 2.5.2 
Release Date    : 01/28/2015 

Firmware Information 
Name      : iDRAC7 
Version     : 2.21.21 (Build 12) 

Firmware Information 
Name      : Lifecycle Controller 2 
Version     : 2.21.21.21 

... che viene convogliata nella seguente dichiarazione awk ...

awk '{ if ($1" "$2 == "BIOS Information") var=$1} END { print var }' 

Questa volontà uscita 'BIOS' in questo caso. Voglio cercare 'BIOS Information' e quindi impostare il terzo campo, due linee in basso, quindi in questo caso 'var' equivale a '2.5.2'. C'è un modo per farlo con awk?

EDIT: Ho provato quanto segue:

awk ' BEGIN { 
FS="[ \t]*:[ \t]*"; 
} 
NF==1 { 
    sectname=$0; 
} 
NF==2 && $1 == "Version" && sectname="BIOS Information" { 
    bios_version=$2; 
} 
END { 
    print bios_version; 
}' 

che mi dà '2.21.21.21' con il testo di cui sopra. Può essere modificato per darmi la prima "Versione" che segue "Informazioni sul BIOS"?

risposta

4

Lo script seguente può essere eccessivo, ma è valido nei casi in cui sono stati modificati più nomi di sezione e/o l'ordine dei campi.

BEGIN { 
    FS="[ \t]*:[ \t]*"; 
} 
NF==1 { 
    sectname=$0; 
} 
NF==2 && $1 == "Version" && sectname=="BIOS Information" { 
    bios_version=$2; 
} 
END { 
    print bios_version; 
} 

Innanzitutto, impostare separatore di campi in ingresso in modo che le parole non sono separati in diversi campi. Successivamente, controllare se la linea corrente è nome della sezione o una coppia valore-chiave. Se è nome della sezione, impostare sectname alla sezione Se è una coppia chiave-valore e il nome della sezione corrente è "Informazioni BIOS" e la chiave è "Versione", impostiamo bios_version.

+0

provato che mi dà la versione per la sezione sbagliata. Ho appena aggiunto una sezione più completa del testo che sto elaborando. Grazie! – user1601716

+0

Risolto. Mancava il segno di uguale qui: 'sectname ==" Informazioni sul BIOS "'. – gudok

+0

Funziona alla grande e posso ampliarlo, grazie! – user1601716

3

Per rispondere alla domanda come chiesto:

awk -v RS= ' 
/^BIOS Information\n/ { 
    for(i=1;i<=NF;++i) { if ($i=="Version") { var=$(i+2); exit } } 
} 
END { print var } 
' file 
  • -v RS= mette awk in modalità punto, in modo che ogni esecuzione di linee non vuoti diventa un singolo record.

  • /^BIOS Information\n/ quindi corrisponde solo a un record (paragrafo) la cui prima riga è uguale a "Informazioni sul BIOS".

  • Ogni paragrafo è internamente ancora divisa in settori da qualsiasi percorso di spazi bianchi (awk 's comportamento di default), in modo che il ciclo for loop su tutti i campi fino a quando trova letterale Version, assegna il 2 ° campo dopo che ad un variabile (perché : viene analizzata come un campo separato) ed esce, a quel punto il valore della variabile viene stampato nel blocco END.

    • Nota: Un modo più robusto e completo per estrarre il numero di versione è disponibile nell'aggiornamento di seguito (l'approccio campo-looping qui potrebbe produrre i falsi positivi e anche sempre e solo riporta il prima (separati da spazi bianchi) token del campo versione).

aggiornamento, in base alle esigenze emerse in seguito:

ad agire per numero di versione ogni del paragrafo e creare variabili individuali:

awk -v RS= ' 

    # Helper function that that returns the value of the specified field. 
    function getFieldValue(name) { 
    # Split the record into everything before and after "...\n<name> : " 
    # and the following \n; the 2nd element of the array thus created 
    # then contains the desired value. 
    split($0, tokens, "^.*\n" name "[[:blank:]]+:[[:blank:]]+|\n") 
    return tokens[2] 
    } 

    /^BIOS Information\n/ { 
    biosVer=getFieldValue("Version") 
    print "BIOS version = " biosVer 
    } 

    /^Firmware Information\n/ { 
    firmVer=getFieldValue("Version") 
    print "Firmware version (" getFieldValue("Name") ") = " firmVer 
    } 

' file 

Con il input di esempio, questo rendimenti:

BIOS version = 2.5.2 
Firmware version (iDRAC7) = 2.21.21 (Build 12) 
Firmware version (Lifecycle Controller 2) = 2.21.21.21 
+0

Che funziona perfettamente, espandendo la domanda. Dal momento che non sto usando se dichiarazioni in questo. Come posso ottenere l'output di tutte e tre le versioni nel testo sopra? come variabili? – user1601716

+0

@ user3554796: Si prega di consultare il mio aggiornamento. – mklement0

+0

Funziona ma non sono in grado di fare riferimento alle variabili a meno che non conosca la loro posizione. la versione di qudok è un po 'più sgraziata, ma mi permette di impostare i nomi delle singole variabili e farvi riferimento più tardi. Grazie! – user1601716

0

Data:

$ echo "$txt" 
BIOS Information 
Manufacturer    : Dell Inc. 
Version     : 2.5.2 
Release Date    : 01/28/2015 

Firmware Information 
Name      : iDRAC7 
Version     : 2.21.21 (Build 12) 

Firmware Information 
Name      : Lifecycle Controller 2 
Version     : 2.21.21.21 

Si può fare:

$ echo "$txt" | awk '/^BIOS Information/{f=1; printf($0)} /^Version/ && f{f=0; printf(":%s\n", $3)}' 
BIOS Information:2.5.2 
Problemi correlati