Jak używać wyrażenia regularnego jako separatora pól w awk?

16

Próbuję użyć wyrażenia regularnego jako separatora pola w awk. Z mojego lektury wydaje się to możliwe, ale nie mogę poprawnie ustawić składni.

rpm -qa | awk '{ 'FS == [0-9]' ; print $1 }'
awk: cmd. line:1: { FS
awk: cmd. line:1:     ^ unexpected newline or end of string

Myśli? Jeśli nie, to celem jest uzyskanie listy oprogramowania bez numeru wersji.

Gray Race
źródło

Odpowiedzi:

25

Zniszczyłeś swoje cytaty i składnię. Aby ustawić separator pól wejściowych, najłatwiej to zrobić za pomocą -Fopcji w wierszu poleceń:

awk -F '[0-9]' '{ print $1 }'

lub

awk -F '[[:digit:]]' '{ print $1 }'

Użyłoby to dowolnej cyfry jako separatora pól wejściowych, a następnie wypisuje pierwsze pole z każdej linii.

[0-9]I [[:digit:]]wyrażenia nie są zupełnie takie same, w zależności od lokalizacji. Patrz „ Różnica między [0–9], [[: cyfra:]] i \ d ”.

Można również ustawić FSw samym awkprogramie. Zwykle odbywa się to w BEGINbloku, ponieważ jest to jednorazowa inicjalizacja:

awk 'BEGIN { FS = "[0-9]" } { print $1 }'

Zauważ, że pojedynczych cudzysłowów nie można używać w ciągach pojedynczych cudzysłowów w powłoce i że awkciągi zawsze używają podwójnych cudzysłowów.

Kusalananda
źródło
12

+1 za odpowiedź Kusalanandy. Alternatywnie zmienną FS można ustawić w bloku BEGIN:

awk 'BEGIN {FS="[0-9]"} {print $1}'

Zmiana FS w bloku akcji nie zadziała, dopóki nie zostanie odczytany następny wiersz

$ printf "%s\n" "abc123 def456" "ghi789 jkl0" | awk '{FS="[0-9]"; print $1}'
abc123
ghi

Inne błędy w pytaniu:

  • nie można używać pojedynczych cudzysłowów w ciągach pojedynczych
  • ==jest operatorem porównania, =służy do przypisywania zmiennych
Glenn Jackman
źródło
1
„Zmiana FS w bloku akcji nie zacznie obowiązywać, dopóki nie zostanie przeczytany następny wiersz”. Szukałem tych informacji w całym tekście.
Samizdis
1
plus: nie można używać pojedynczych cudzysłowów dla wartości ciągu w awk, nawet jeśli poprawnie przekazujesz je z powłoki
dave_thompson_085