2013-03-27 14 views
6

W jaki sposób przydzielisz "null" wartość do odczytu?awk - jeśli kolumna = null

Jestem pewien, że istnieje na to ustalona postać, po prostu nie mogę jej znaleźć.

Na przykład

Mam ciąg awk tak:

awk ' 
$3==24{print "stuff"} 
$3==23{print "stuff"} 
' 

muszę wiedzieć, w jaki sposób uwzględniać pustych colums wykorzystujących ten sam format, tak, że jeśli $ 3 = puste { print "stuff"}

Dzięki!

+0

Jeśli "$ 3" jest puste, czy spodziewasz się mieć niepuste wartości dla "4 $" itp. W tym samym wierszu? Co się dzieje z $ 3 == "" jako warunek? –

+0

3 USD to ostatnia kolumna w pliku. Niektóre wiersze mają tylko dwie kolumny: – Numpty

+1

Tak więc 'NF == 2' lub' NF == 3' mówi, czy 3 $ jest ustawione, czy nie? Nawiasem mówiąc, możesz pomyśleć o użyciu '$ 3 == 24 {print" stuff "; next} "jako działanie, ponieważ to zapisuje' awk' sprawdzając, czy 24 jest równe 23 (nie jest). –

Odpowiedz

9

Spróbuj zrobić tak:

awk ' 
    $3==24{print "stuff"} 
    $3==23{print "stuff"} 
    !$3{print "null"} 
' file.txt 

Jeśli trzeba przetwarzać $3 jeśli jest zero (false dla awk), spróbuj to zrobić:

!$3 && $3 != 0{print "null"} 
+1

Yuuuup, musiałem zmienić! 1 $ na! 3 $ :) – Numpty

+1

Jeszcze raz dziękuję Sputnick! – Numpty

+0

wpis edytowany odpowiednio –

7

zalega przetwarzania awk, nie ma czegoś takiego jako "pusta" kolumna.

Pola są rozdzielane białymi znakami, tj. Jednym znakiem lub więcej (w zasadzie tabulatory i spacje). Tak więc biorąc pod uwagę to wejście:

this that the_other 
foo  bar 

na pierwszej linii $1, $2 i $3this, that i the_other, odpowiednio, ale w drugiej linii bar jest $2, niezależnie od tego, ile wykroje są między pierwsze i drugie pola.

Można mieć pustych pól, jeśli określić inny separator pól:

$ (echo 'this:that:the_other' ; echo 'foo::bar') | awk -F: '{print $3}' 
the_other 
bar 

Lub, jeśli wolisz, aby ustawić separator pól w skrypcie samego:

$ (echo 'this:that:the_other' ; echo 'foo::bar') | \ 
    awk 'BEGIN { FS = ":" } {print $3}' 
the_other 
bar 

Ale można użyć wyrażenie regularne jako separator pól:

$ (echo 'this that the_other' ; echo 'foo bar') | \ 
    awk 'BEGIN { FS = "[ ]" } {print $3}' 
the_other 
bar 

(Niektóre bardzo stare implementacje awk mogą nie obsługiwać tutaj wyrażeń regularnych.)

Wyrażenie regularne "[ ]" nie otrzymuje takiego samego specjalnego traktowania, jak znak spacji.

Odniesienia do instrukcji GNU awk:

Default field splitting:

Pola są zwykle oddzielone odstępami sekwencji (przestrzeni, kart nowa linia), a nie pojedyncze miejsca. Dwie spacje z rzędu nie ograniczają pustego pola przez .Domyślna wartość separatora pól FS to ciąg znaków zawierający pojedynczą spację, " ". Jeśli awk zinterpretował tę wartość w zwykły sposób, każdy znak spacji miałby osobne pola, więc dwie spacje w jednym wierszu tworzyłyby puste pole między nimi. Powodem nie jest to, że pojedyncza spacja jako wartość FS jest szczególnym przypadkiem - określa się domyślny sposób wydzielania pól .

Jeśli jest jakikolwiek inny pojedynczy znak, taki jak ",", wówczas każde wystąpienie tej litery oddziela dwa pola. Dwa kolejne wystąpienia ograniczają puste pole. Jeśli znak występuje na początku lub na końcu linii, to również ogranicza puste pole. Znak spacji jest jedynym pojedynczym znakiem, który nie spełnia tych reguł.

i Using Regular Expressions to Separate Fields.

Ale bądź ostrożny z tym; albo będziesz musiał zmodyfikować plik, aby użyć innego separatora, albo twoje przetwarzanie będzie czułe na liczbę pustych pól pomiędzy polami (foo bar (z jednym pustym znakiem) będzie różne od foo bar (z dwoma odstępami)).

W zależności od aplikacji, możesz rozważyć analizowanie linii według numeru kolumny, a nie przez pola rozpoznawane przez awk.

+2

wrt '" przynajmniej w GNU Awk, możesz użyć wyrażenia regularnego jako separatora pól "" - tak jest w przypadku wszystkich błędów. GNU awk jest wyjątkowy pod tym względem, pozwalając również, aby RS było wyrażeniem regularnym. –

+0

Dzięki za wyjaśnienie - nie złapałem tego wcześniej – Numpty

Powiązane problemy