Podívejme se na manuálovou stránku GNU awk:
FS— Oddělovač vstupního pole, ve výchozím nastavení mezera. Viz Pole , výše.
Na Pole sekce!
Když je každý vstupní záznam načten, gawk rozdělí záznam do polí pomocí hodnoty
FSproměnná jako oddělovač pole. PokudFSje jeden znak, pole jsou oddělena tímto znakem. PokudFSje nulový řetězec, pak se každý jednotlivý znak stane samostatným polem. JinakFSočekává se, že bude úplný regulární výraz. Ve speciálním případě, žeFSje jedna mezera, pole jsou oddělena řadou mezer a/nebo tabulátorů a/nebo nových řádků.
Zde je pragmatické shrnutí to platí pro všechny hlavní implementace Awk :
- GNU Awk (
gawk) – výchozíawkv některých Linuxové distribuce - Mawk (
mawk) – výchozíawkv některých Linuxové distribuce (např. starší verze Ubuntu) - BWK Awk – výchozí
awkna platformách podobných BSD, včetně macOS
Poslední verze všech tyto implementace se řídí standardem POSIX s ohledem na pole oddělovače (ale ne záznam oddělovače).
Glosář:
-
RSje vstup-záznam oddělovač , která popisuje, jak je vstup rozdělen do záznamů :- Výchozí hodnota nařízená POSIX je nový řádek , také označovaný jako
\nníže; to znamená, že vstup je rozdělen do řádků ve výchozím nastavení . - Na
awk's příkazový řádek,RSlze zadat jako-v RS=<sep>. - POSIX omezuje
RSna doslovný, jednoznakový hodnotu, ale GNU Awk a Mawk podporují víceznakové hodnoty, které mohou být rozšířenými regulárními výrazy (BWK Awk nedělá podporujte to).
- Výchozí hodnota nařízená POSIX je nový řádek , také označovaný jako
-
FSje vstupní-pole oddělovač , která popisuje, jak každý záznam je rozdělena do polí ; může to být rozšířený regulární výraz .- Na
awk's příkazový řádek,FSlze zadat jako-F <sep>(nebo-v FS=<sep>). - Výchozí hodnota nařízená standardem POSIX je formálně mezera (
0x20), ale tento prostor není doslova interpretován jako (jediný) oddělovač, ale má zvláštní význam ; viz níže.
- Na
Ve výchozím nastavení :
- jakýkoli běh z mezer a/nebo karty a/nebo nové řádky je považováno za oddělovač polí
- s ignorováním úvodních a koncových běhů .
Všimněte si, že s výchozím oddělovačem vstupního záznamu (RS ), \n , nové řádky obvykle nevkládejte obrázek jako oddělovače polí , protože žádný záznam samotný obsahuje \n v tom případě.
Nové řádky jako oddělovače polí dělají vstoupit do hry , nicméně:
- Když
RSje nastavena na hodnotu, která vede k samotným záznamům obsahující\ninstance (například kdyžRSje nastaven na prázdný řetězec; viz níže). - Obecně , když
split()Funkce se používá k rozdělení řetězce na prvky pole bez argumentu oddělovače explicitních polí.- I když vstupní záznamy nebude obsahovat
\ninstance v případě, že výchozíRSplatí,split()funkce při vyvolání bez explicitního argumentu oddělovače polí na víceřádkovém řetězci z jiného zdroje (např. proměnná předaná prostřednictvím-vmožnost nebo jako pseudonázev souboru) vždy zpracovává\njako oddělovač polí.
- I když vstupní záznamy nebude obsahovat
Důležité informace, které nejsou výchozí :
-
Přiřazení prázdného řetězec na
RSmá zvláštní význam :čte vstup v režimu odstavce , což znamená, že vstup je rozdělen do záznamů podle běhů neprázdných řádků , přičemž začátek a konec prázdných řádků jsou ignorovány . -
Když přiřadíte cokoli jiného než doslov mezera na
FS, interpretaceFSzásadně se mění :- A single znak nebo každý znak ze zadané znakové sady je uznáván individuálně jako oddělovač polí - ne běží stejně jako u výchozího nastavení.
- Například nastavení
FSna[ ]- i když to efektivně se rovná jedné mezerě – způsobuje každý jednotlivec instance prostoru v každém záznamu, která má být považována za oddělovač polí. - Pro rozpoznání běhů , kvantifikátor regulárního výrazu (symbol duplikace)
+musí být použit; např.[\t]+rozpozná běhy tabulátorů jako jeden oddělovač.
- Například nastavení
- Přední a koncové oddělovače NEJSOU ignorovány a místo toho oddělte prázdné pole.
- Nastavení
FSna prázdný řetězec znamená, že každý znak záznamu je jeho vlastní pole .
- A single znak nebo každý znak ze zadané znakové sady je uznáván individuálně jako oddělovač polí - ne běží stejně jako u výchozího nastavení.
-
Podle nařízení POSIX, pokud
RSje nastaven na prázdný řetězec (režim odstavce), nové řádky (\n) jsou také považovány za oddělovače polí , bez ohledu na hodnotuFS.
- S
-Pv platnosti aRSnastavte na prázdný řetězec ,\nje stále považováno za oddělovač pole:
gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb' - S
-Pv platnosti a neprázdnéRS,\nNENÍ považováno za oddělovač polí – toto je zastaralé chování:
gawk -P -F' ' -v RS='|' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
Přichází oprava , podle správců GNU Awk; očekávejte to ve verzi 4.2 (není uveden časový rámec).
(Hrot klobouku @JohnKugelman a @EdMorton za jejich pomoc.)
'[ ]+' mi funguje. Spusťte awk -W version získat verzi awk. Můj je GNU Awk 4.0.2 .
# cat a.txt
tcp 0 0 10.192.25.199:65002 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:26895 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:18422 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 10.192.25.199:8888 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:50010 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:50075 0.0.0.0:* LISTEN
tcp 0 0 10.192.25.199:8093 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8670 0.0.0.0:* LISTEN
Například chci získat port Listen. Takže musím použít výchozí oddělovač awk přidaný s ':'
# cat a.txt | awk -F '[ ]+|:' '{print $5}'
65002
26895
111
18422
22
8888
50010
50075
8093
8670
Pokud chcete pouze otestovat výchozí oddělovač, můžete spustit
# cat a.txt | awk -F '[ ]+' '{print $4}'
10.192.25.199:65002
127.0.0.1:26895
0.0.0.0:111
0.0.0.0:18422
0.0.0.0:22
10.192.25.199:8888
0.0.0.0:50010
0.0.0.0:50075
10.192.25.199:8093
0.0.0.0:8670
Výsledek je podle očekávání.
Otázka the default delimiter is only space for awk? je nejednoznačný, ale pokusím se odpovědět na obě otázky, na které se možná ptáte.
Výchozí hodnota FS proměnná (která obsahuje oddělovač polí, který awk říká, jak rozdělit záznamy do polí při jejich čtení) je jedna mezera.
Věc, kterou awk používá k oddělení záznamů do polí, je "oddělovač polí", což je regulární výraz s některými dalšími funkcemi, které se používají pouze v případě, že oddělovačem polí je jeden prázdný znak. Tato další funkce je následující:
- Během rozdělování polí jsou ignorovány úvodní a koncové mezery.
- Pole jsou oddělena řetězci souvislých mezer, které zahrnují mezery, tabulátory a nové řádky.
- Pokud chcete jako oddělovač polí použít doslovný prázdný znak, musíte jej zadat jako
[ ]namísto pouhého samostatného doslovného prázdného znaku, jako byste mohli v regulárním výrazu.
Kromě oddělovačů polí, které se používají k rozdělení záznamů do polí při čtení vstupu, se používají v některých jiných kontextech, např. 3. argument pro split() , takže je důležité, abyste věděli, které kontexty vyžadují řetězec nebo regulární výraz nebo fieldep a manuálová stránka každý z nich jasně specifikuje.
Výše uvedené mimo jiné vysvětluje toto:
$ echo ' a b c ' | awk '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F' ' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F'[ ]' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
5: <> <a> <b>
takže pokud nerozumíte tomu, proč první 2 produkují stejný výstup, ale poslední je jiný, zeptejte se.