2016-06-03 16 views
5

Ich habe den folgenden Text ...awk Setvariable Linie nach if-Anweisung Spiel

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 

..., die in den folgenden awk-Anweisung geleitet wird ...

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

Dieser Wille Ausgabe "BIOS" in diesem Fall. Ich möchte nach 'BIOS Information' suchen und dann das dritte Feld, zwei Zeilen nach unten setzen, in diesem Fall würde 'var' gleich '2.5.2' sein. Gibt es eine Möglichkeit, dies mit awk zu tun?

EDIT: Ich habe versucht, die folgenden:

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

Was mich '2.21.21.21' mit dem obigen Text gibt. Kann dies geändert werden, um mir die erste "Version" nach "BIOS Information" zu geben?

Antwort

4

Das folgende Skript ist möglicherweise ein Overkill, aber es ist robust in Fällen, wenn Sie mehrere Abschnittsnamen und/oder Reihenfolge der Felder geändert haben.

Abschnittsname oder ein Schlüssel-Wert-Paar
BEGIN { 
    FS="[ \t]*:[ \t]*"; 
} 
NF==1 { 
    sectname=$0; 
} 
NF==2 && $1 == "Version" && sectname=="BIOS Information" { 
    bios_version=$2; 
} 
END { 
    print bios_version; 
} 

Erstens setzen wir Separator Eingabefeld, so dass Worte nicht in verschiedene Felder getrennt. Als nächstes prüfen wir, ob die aktuelle Zeile ist. Wenn es Abschnittsname ist, eingestellt sectname Abschnitt Wenn es sich um ein Schlüssel/Wert-Paar handelt und der aktuelle Abschnittsname "BIOS Information" lautet und der Schlüssel "Version" lautet, setzen wir bios_version.

+0

es versucht, die mir die Version für den falschen Abschnitt gibt. Ich habe gerade einen vollständigeren Abschnitt des Textes hinzugefügt, der im Prozess ist. Vielen Dank! – user1601716

+0

Behoben. Hier fehlte das Gleichheitszeichen: 'sectname ==" BIOS Information "'. – gudok

+0

Funktioniert gut und ich kann das weiter ausbauen, Danke! – user1601716

3

Zur Beantwortung der Frage, wie gestellt:

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= setzt awk in Absatz-Modus, so dass jeder Lauf von nicht-leeren Zeilen ein einzelner Datensatz wird.

  • /^BIOS Information\n/ dann entspricht nur ein Datensatz (Absatz), dessen erste Zeile gleich "BIOS Information" ist.

  • Jeder Absatz intern wird immer noch von jedem Lauf von Leerzeichen in Felder aufgeteilt (awk ‚s Standardverhalten), so dass die for Schleife alle Felder Schleifen über, bis er wörtliche Version findet, die, nachdem sie auf ein 2. Feld zuweist Variable (weil : wird als separates Feld analysiert) und beendet, an dem der Variablenwert im END Block gedruckt wird.

    • Hinweis: Eine robuste und vollständige Art und Weise der Versionsnummer zu extrahieren kann hier unten (Feld-Looping-Ansatz in dem Update gefunden werden können Fehlalarme ergeben und auch nur jemals berichtet die erste (durch Leerzeichen getrennt) Token des Versionsfeldes).

aktualisieren, Anforderungen basierend auf, die später entstanden:

Handeln auf jeden Versionsnummer des Absatzes und erstellen einzelne Variablen:

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 

Mit dem Abtastwerteingang, ergibt dies:

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

Das funktioniert perfekt und erweitert die Frage. Da ich keine if-Anweisungen dazu verwende. Wie kann ich die Ausgabe aller drei Versionen im obigen Text erhalten? als Variablen? – user1601716

+0

@ user3554796: Bitte sehen Sie mein Update. – mklement0

+0

Das funktioniert, aber ich kann nicht auf die Variablen verweisen, wenn ich nicht weiß, wo sie fallen. Die Version von qudok ist ein wenig unpräziser, aber ich kann einzelne Variablennamen festlegen und sie später referenzieren. Vielen Dank! – user1601716

0

Gegeben:

$ 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 

Sie tun können:

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