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: 
użytkownik173446
źródło

Odpowiedzi:

382

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

 echo "1: " | awk -F  ":" '/1/ {print $1}'
Jürgen Hötzel
źródło
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.

Wstrzymano do odwołania.
źródło
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
fedorqui „SO przestań szkodzić”
źródło
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,
@kvantour good point. Właśnie o to zapytałem w Dlaczego separator pól jest różnie brany pod uwagę, jeśli jest ustawiony przed lub po wyrażeniu? .
fedorqui „SO przestań krzywdzić”
12

-Fjest awksam w sobie argumentem :

$echo "1: " | awk -F":" '/1/ {print $1}'
1
Danben
źródło
2
Nie ma potrzeby cytowania jelita grubego.
ceving 10.04.17
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}'
Zlemini
źródło
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
Bhavuk Taneja
źródło
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ę ...

jihed gasmi
źródło
2

Lub możesz użyć:

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

To naprawdę zabawne równanie.

Vonton
źródło
1
co /1/znaczy
Znajdź wzór. W tym przypadku „1”
José Dias