2016-06-03 35 views
5

Mam następujący tekst ...awk ustawić zmienną do linii po if mecz

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 

... który jest wyprowadzony na następującym stwierdzeniem awk ...

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

Ta wola wyjście "BIOS" w tym przypadku. Chcę wyszukać "Informacje o systemie BIOS", a następnie ustawić trzecie pole, dwie linie w dół, więc w tym przypadku "var" będzie równy "2.5.2". Czy jest jakiś sposób, aby to zrobić w awk?

EDIT: Próbowałem następujące:

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

co daje mi '2.21.21.21' z powyższego tekstu. Czy można to zmienić, aby dać mi pierwszą "Wersję" po "Informacje o BIOSie"?

Odpowiedz

4

Poniższy skrypt może być przesadą, ale jest solidny w przypadkach, gdy masz wiele nazw sekcji i/lub kolejność pól jest zmieniana

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

Najpierw ustalamy separator pól wejściowych tak, że słowa nie są podzielone na różnych polach. Następnie sprawdzamy, czy obecna linia jest nazwa sekcji lub parę klucz-wartość. Jeśli jest to nazwa sekcji, ustaw sectname do sekcji Jeśli jest to para klucz-wartość, a nazwa bieżącej sekcji to "Informacje o systemie BIOS", a klucz to "Wersja", wówczas ustawiamy bios_version.

+0

Próbowaliśmy go, który daje mi Wersja dla złym dziale. Właśnie dodałem bardziej kompletny fragment tekstu, który im przetwarzanie. Dzięki! – user1601716

+0

Naprawiono. Brak tu znaku równości: 'sectname ==" Informacje o systemie BIOS "'. – gudok

+0

Działa świetnie i mogę to rozwinąć, dzięki! – user1601716

3

Aby odpowiedzieć na pytanie, jak poprosił:

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= stawia awk w trybie ust, tak, że każdy bieg niepustych wierszy staje się pojedynczy rekord.

  • /^BIOS Information\n/ następnie dopasowuje tylko rekord (akapit), którego pierwszy wiersz jest równy "Informacje o systemie BIOS".

  • Każdy akapit jest wewnętrznie nadal podzielone na pola o dowolnym przebiegu spacji (awk „s zachowanie domyślne), więc pętla for pętli nad wszystkie pola aż znajdzie dosłowne Version, przypisuje 2nd pole po go do zmienna (ponieważ : jest analizowana jako oddzielne pole) i kończy działanie, w którym to momencie wartość zmiennej jest drukowana w bloku END.

    • Uwaga: Bardziej wytrzymałe i kompletny sposób, aby wyodrębnić numer wersji można znaleźć w aktualizacji poniżej (podejścia polowego-zapętlenie tutaj mogłoby przynieść fałszywych alarmów, a także zawsze tylko raporty pierwszy (białe znaki rozdzielone ) token pola wersji).

Aktualizacja, w oparciu o wymagania, które pojawiły się później:

Działać na numer wersji każdego akapitu i tworzyć zmienne indywidualne:

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 

Dzięki Wejście próbki Daje:

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

To działa idealnie, rozwijając się na pytanie. Ponieważ nie używam, jeśli instrukcje w tym. Jak mogę uzyskać dane wyjściowe wszystkich trzech wersji w powyższym tekście? jako zmienne? – user1601716

+0

@ user3554796: Proszę zobaczyć moją aktualizację. – mklement0

+0

Działa to, ale nie mogę odwoływać się do zmiennych, chyba że wiem, gdzie one spadną. Wersja qudoka jest nieco bardziej niegodna, ale pozwala ustawić indywidualne nazwy zmiennych i odsyłać je później. Dzięki! – user1601716

0

Dane:

$ 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 

można zrobić:

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