GNU/Linux >> Znalost Linux >  >> Linux

Výchozí oddělovač polí pro awk

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 FS proměnná jako oddělovač pole. Pokud FS je jeden znak, pole jsou oddělena tímto znakem. Pokud FS je nulový řetězec, pak se každý jednotlivý znak stane samostatným polem. Jinak FS očekává se, že bude úplný regulární výraz. Ve speciálním případě, že FS je 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í awk v některých Linuxové distribuce
  • Mawk (mawk ) – výchozí awk v některých Linuxové distribuce (např. starší verze Ubuntu)
  • BWK Awk – výchozí awk na 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ář:

  • RS je 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 \n níže; to znamená, že vstup je rozdělen do řádků ve výchozím nastavení .
    • Na awk 's příkazový řádek, RS lze zadat jako -v RS=<sep> .
    • POSIX omezuje RS na 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).
  • FS je 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, FS lze 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.

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ž RS je nastavena na hodnotu, která vede k samotným záznamům obsahující \n instance (například když RS je 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 \n instance v případě, že výchozí RS platí, 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 -v možnost nebo jako pseudonázev souboru) vždy zpracovává \n jako oddělovač polí.

Důležité informace, které nejsou výchozí :

  • Přiřazení prázdného řetězec na RS má 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 , interpretace FS zá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í FS na [ ] - 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č.
    • Přední a koncové oddělovače NEJSOU ignorovány a místo toho oddělte prázdné pole.
    • Nastavení FS na prázdný řetězec znamená, že každý znak záznamu je jeho vlastní pole .
  • Podle nařízení POSIX, pokud RS je 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 hodnotu FS .

  • S -P v platnosti a RS nastavte na prázdný řetězec , \n je stále považováno za oddělovač pole:
    gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
  • S -P v platnosti a neprázdné RS , \n NENÍ 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í:

  1. Během rozdělování polí jsou ignorovány úvodní a koncové mezery.
  2. Pole jsou oddělena řetězci souvislých mezer, které zahrnují mezery, tabulátory a nové řádky.
  3. 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.


Linux
  1. 9 výkonných vestavěných funkcí Awk pro numerické funkce

  2. Jak přidat výchozí zahrnutou cestu pro GCC v Linuxu?

  3. příkaz cut nebo awk pro tisk prvního pole prvního řádku

  1. Co tvoří „pole“ pro příkaz cut?

  2. Seřadit pomocí oddělovače polí

  3. Jaký je výchozí soubor pro `hostname`?

  1. Jak nastavit výchozí možnosti automatického připojení pro vyměnitelná média?

  2. Jak změnit výchozí délku čáry pro Od a Hexdump?

  3. Jak změnit pole Od:pro e-maily z Cronu?