Jak używać „:” jako separatora pól awk?


243

Biorąc pod uwagę następujące polecenie:

echo "1: " | awk '/1/ -F ":" {print $1}'

dlaczego awk wyświetla:

1: 

Odpowiedzi:


382

„-F” to argument wiersza poleceń, a nie składnia awk, spróbuj:

 echo "1: " | awk -F  ":" '/1/ {print $1}'

42
Pytanie Ignoranta: część / 1 / ma powiedzieć awk, aby przetwarzało tylko wiersze (lub dokładniej rekordy), które zawierają numer 1, prawda?
rantsh

3
Wygląda na składnię @rantsh Awk (pattern){action}. Jeśli pattern(głównie instrukcja warunkowa) jest prawdziwa , actionjest wykonywana. Jeśli patternnie jest dostępny, truesugeruje się. Tutaj patternjest /1/w którym stwierdza się regex 1dopasowane w bieżącym rekordzie$0
kvantour

62

Jeśli chcesz to zrobić programowo, możesz użyć FSzmiennej:

echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'

Zauważ, że jeśli zmienisz go w głównej pętli, a nie w BEGINpętli, będzie to miało wpływ na następną odczytaną linię, ponieważ bieżąca linia została już podzielona.


35

Istnieje wiele sposobów ustawienia :jako separatora:

awk -F: '{print $1}'

awk -v FS=: '{print $1}'

awk '{print $1}' FS=:

awk 'BEGIN{FS=":"} {print $1}'

Wszystkie z nich są równoważne i dla zwrócą 1przykładowe dane wejściowe „1: 2: 3”:

$ awk -F: '{print $1}' <<< "1:2:3"
1
$ awk -v FS=: '{print $1}' <<< "1:2:3"
1
$ awk '{print $1}' FS=: <<< "1:2:3"
1
$ awk 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
1

jaki jest preferowany sposób? zakładam, że ostatni przykład z BEGINinstrukcją byłby najbardziej poprawny (zgodny z ogólną awkskładnią).

1
@ randomware wszystkie są w porządku. Zwykle używam, BEGINjeśli używam pliku do przechowywania całej rzeczy, podczas gdy -Fprzydaje się w przypadku jednowarstwowych.
fedorqui „SO przestań krzywdzić”

1
Trzeba powiedzieć, że istnieją subtelne różnice między trzecim przypadkiem a wszystkimi innymi. Przykład: awk 'BEGIN{print split("foo:bar",a)}' FS=":" fileiawk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
kvantour,



6

Możesz także użyć wyrażenia regularnego jako separatora pól, następujące polecenie wydrukuje „pasek” za pomocą wyrażenia regularnego, aby ustawić liczbę „10” jako separator.

echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'

4

Nie musisz tyle pisać. Po prostu umieść żądany separator pól z opcją -F w poleceniu awk, a numer kolumny, którą chcesz wydrukować, posegreguj zgodnie ze wspomnianym separatorem pól.

echo "1: " | awk -F: '{print $1}'    
1

echo "1#2" | awk -F# '{print $1}'  
1

4

AWK działa jako interpreter tekstu, który przebiega liniowo dla całego dokumentu i który jest zgodny z polem dla każdego wiersza, dlatego 1 $, 2 $ .. $ n to odniesienia do pól każdej linii (1 $ to pierwsze pole, 2 $ to drugie pole i tak dalej ...) Możesz zdefiniować separator pól za pomocą przełącznika „-F” pod wierszem poleceń lub w dwóch nawiasach kwadratowych za pomocą „FS = ...”. Rozważmy teraz odpowiedź „JUERGEN”:

echo "1: " | awk -F  ":" '/1/ {print $1}'

Powyżej granic pól są ustawione przez „:”, więc mamy dwa pola $ 1, które jest „1” i 2 $, które JEST pustą przestrzenią. Następnie pojawia się wyrażenie regularne „/ 1 /”, które instruuje filtr, aby wyprowadzał tylko pierwsze pole kiedy tłumacz natknie się na linię zawierającą takie wyrażenie (mam na myśli 1); Dane wyjściowe polecenia „echo” to jeden wiersz zawierający „1”, więc filtr będzie działał ...

W przypadku następującego przykładu:

echo "1: " | awk '/1/ -F ":" {print $1}'

Składnia jest niechlujna, a tłumacz zdecydował się zignorować część F „:” i przełącza się na domyślny rozdzielacz pól, który jest pustą przestrzenią, a tym samym wypisuje „1:” jako pierwsze pole i nie będzie drugiego pola!

Odpowiedź JUERGEN zawiera dobrą składnię ...


2

Lub możesz użyć:

echo "1: " | awk  '/1/{print $1-":"}' 

To naprawdę zabawne równanie.


1
co /1/znaczy

Znajdź wzór. W tym przypadku „1”
José Dias
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.