Używanie wielu ograniczników w awk


202

Mam plik zawierający następujące wiersze:

/logs/tc0001/tomcat/tomcat7.1/conf/catalina.properties:app.env.server.name = demo.example.com
/logs/tc0001/tomcat/tomcat7.2/conf/catalina.properties:app.env.server.name = quest.example.com
/logs/tc0001/tomcat/tomcat7.5/conf/catalina.properties:app.env.server.name = www.example.com

W powyższym wyjściu chcę wyodrębnić 3 pola (numer 2, 4 i ostatnie *.example.com). Otrzymuję następujące dane wyjściowe:

cat file | awk -F'/' '{print $3 "\t" $5}'
tc0001   tomcat7.1
tc0001   tomcat7.2
tc0001   tomcat7.5

Jak wyodrębnić ostatnie pole z nazwą domeny, która jest później '='? Jak użyć multiple delimiterdo wyodrębnienia pola?


2
Aby odpowiedzieć na moje pytanie, które jest takie samo, ale inne, awkprzełykałem pola, gdy były puste, co oznaczało numerację pól. Zmieniłem -F " "się -F "[ ]"i awkjuż nie połykałem pustych pól.
— Adam

Odpowiedzi:


324

Separator może być wyrażeniem regularnym.

awk -F'[/=]' '{print $3 "\t" $5 "\t" $8}' file

Produkuje:

tc0001   tomcat7.1    demo.example.com  
tc0001   tomcat7.2    quest.example.com  
tc0001   tomcat7.5    www.example.com

42
Oczywiście, catproces ten nie jest wymagane: awk '...' file. Również bardziej pomocne byłoby użycie separatora pola wyjściowego:awk -F'[/=]' -v OFS="\t" '{print $3, $5, $8}'
— glenn jackman

17
Ograniczniki Awk mogą być wyrażeniami regularnymi ... to sprawiło, że mój dzień!
— das.cyklone

4
@ das.cyklone: awk może mieć również kilka separatorów, z |: Ex: awk -F 'this|that|[=/]' '......' (usefull mieć słów / łańcuchy oddzielające rzeczy) (uwaga, że ta utrzymuje przestrzenie w fiels między 2 separatory Dodawanie również. |[ \t]+mogą być przydatne, ale można zrobić rzeczy trudne ... ponieważ przed i po tym są często spacje, między tymi polami i „tym” pojawią się 2 dodatkowe puste pola
— Olivier Dulac

Próbowałem tego na 2 różnych dystrybucjach i mam takie samo zachowanie: Chcę uzyskać port z netstat -ntpl "netstat -ntpl | sed 's /: / /' | awk '{print $ 5}'” działa, ale da się obejść bez instalacji doulbe Działa to, ale nie spodziewałem się danych w polu 17: "netstat -ntpl | awk -F" |: "'{print 17 $}'"
— louigi600

2
tak ... dostałem to, czego chciałem: awk -F "[:] +" '/ \ / postmaster * $ / {print $ 5}'
— louigi600

44

Dobre wieści! awkseparator pól może być wyrażeniem regularnym. Musisz tylko użyć -F"<separator1>|<separator2>|...":

awk -F"/|=" -vOFS='\t' '{print $3, $5, $NF}' file

Zwroty:

tc0001  tomcat7.1  demo.example.com
tc0001  tomcat7.2  quest.example.com
tc0001  tomcat7.5  www.example.com

Tutaj:

  • -F"/|="ustawia separator pola wejściowego na jeden /lub =. Następnie ustawia separator pola wyjściowego na tabulator.

  • -vOFS='\t'używa -vflagi do ustawiania zmiennej. OFSjest zmienną domyślną dla Separatora pól wyjściowych i jest ustawiony na znak tabulacji. Flaga jest konieczna, ponieważ nie ma wbudowanego dla OFS jak -F.

  • {print $3, $5, $NF} drukuje 3., 5. i ostatnie pole na podstawie separatora pól wejściowych.


Zobacz inny przykład:

$ cat file
hello#how_are_you
i#am_very#well_thank#you

Ten plik ma dwa separatory pól #i _. Jeśli chcemy wydrukować drugie pole niezależnie od tego, czy separator jest jednym, czy drugim, niech oba będą separatorami!

$ awk -F"#|_" '{print $2}' file
how
am

Gdzie pliki są ponumerowane w następujący sposób:

hello#how_are_you           i#am_very#well_thank#you
^^^^^ ^^^ ^^^ ^^^           ^ ^^ ^^^^ ^^^^ ^^^^^ ^^^
  1    2   3   4            1  2   3    4    5    6

1
Dzięki @BUFU za edycję. Usunąłem odniesienie do OFS, aby skupić się tylko na części FS, ale dobrze jest też to mieć. Twoje zdrowie!
— fedorqui „SO przestań krzywdzić”

5

Jeśli biała spacja jest spójna, możesz użyć jej jako separatora, a także zamiast \tbezpośredniego wstawiania , możesz ustawić separator wyjściowy i zostanie on dołączony automatycznie:

< file awk -v OFS='\t' -v FS='[/ ]' '{print $3, $5, $NF}'

3

Dla separatora pól dowolnej liczby 2przez 5lub listownie alub #lub miejsca, w którym znak oddzielający należy powtórzyć co najmniej 2 razy i nie więcej niż 6 razy, na przykład:

awk -F'[2-5a# ]{2,6}' ...

Jestem pewien, że istnieją odmiany tego przy użyciu () i parametrów


3

Perl One-Liner:

perl -F'/[\/=]/' -lane 'print "$F[2]\t$F[4]\t$F[7]"' file

Używane są następujące opcje wiersza polecenia:

  • -npętla wokół każdej linii pliku wejściowego, wstaw linię do $_zmiennej, nie drukuj automatycznie każdej linii

  • -l usuwa nowe linie przed przetwarzaniem i dodaje je z powrotem

  • -atryb autosplit - perl automatycznie podzieli linie wejściowe na @Ftablicę. Domyślnie podział na białe znaki

  • -Fmodyfikator autosplit, w tym przykładzie dzieli się na jeden /lub=

  • -e wykonaj kod perla

Perl jest ściśle związany z awk, jednak @Ftablica autosplit zaczyna się od indeksu, $F[0]a pola awk zaczynają się od 1 $.


2

Innym jest użycie opcji -F, ale przekazanie wyrażenia regularnego w celu wydrukowania tekstu między lewym i prawym nawiasiem ().

Zawartość pliku:

528(smbw)
529(smbt)
530(smbn)
10115(smbs)

Komenda:

awk -F"[()]" '{print $2}' filename

wynik:

smbw
smbt
smbn
smbs

Za pomocą awk wystarczy wydrukować tekst pomiędzy []:

Użyj, awk -F'[][]' ale awk -F'[[]]'nie zadziała.

http://stanlo45.blogspot.com/2020/06/awk-multiple-field-separators.html


Twoja odpowiedź pojawiła się w kolejce usuwania, ponieważ 9 razy na 10 użytkownicy z 1 reputacją prowadzącą do własnego bloga to zazwyczaj spam. Ale twój jest wyjątkiem od reguły. Ostatnie 10 lat treści to kopalnia złota, mam nadzieję, że masz plan, aby ją uwiecznić.
— Eric Leschinski

0

Widzę wiele doskonałych odpowiedzi na tablicy, ale nadal chciałbym przesłać mój kawałek kodu,

awk -F"/" '{print $3 " " $5 " " $7}' sam | sed 's/ cat.* =//g'


2
print $3 " " $5 " " $7można wydrukować tak jak print $3, $5, $7. Poza tym nie widzę korzyści z używania awk, a następnie pipowania do sed. Ogólnie rzecz biorąc, awk może wystarczyć, a inne odpowiedzi to pokazują.
— fedorqui „SO przestań krzywdzić”
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.