GNU/Linux >> Znalost Linux >  >> Linux

Vysvětlení příkazu awk pomocí ORS, NR, FS, RS

% je operátor modulo (viz https://en.wikipedia.org/wiki/Modulo_operation) a NR%3?FS:RS je ternární výraz (viz https://en.wikipedia.org/wiki/%3F:). To jsou oba běžné konstrukce v mnoha programovacích jazycích, nejsou specifické pro awk. Pro význam ORS, NR, FS a RS se podívejte na manuálovou stránku awk.

Spusťte toto, abyste viděli hodnoty proměnných v kódu před a za příkazem, který provádíte:

$ cat tst.awk
BEGIN {
    printf "%s=\"%s\"\n", "RS", RS
    printf "%s=\"%s\"\n", "FS", FS
}
{
    printf "---\n"

    printf "%s=\"%s\"\n", "$0", $0
    printf "%s=\"%s\"\n", "NR", NR
    printf "%s=\"%s\"\n", "NR%3", NR%3

    printf "before) %s=\"%s\"\n", "ORS", ORS

    ORS = (NR%3 ? FS : RS)

    printf "after) %s=\"%s\"\n", "ORS", ORS
}

.

$ awk -f tst.awk file
RS="
"
FS=" "
---
$0="1"
NR="1"
NR%3="1"
before) ORS="
"
after) ORS=" "
---
$0="2"
NR="2"
NR%3="2"
before) ORS=" "
after) ORS=" "
---
$0="3"
NR="3"
NR%3="0"
before) ORS=" "
after) ORS="
"
---
$0="4"
NR="4"
NR%3="1"
before) ORS="
"
after) ORS=" "
---
$0="5"
NR="5"
NR%3="2"
before) ORS=" "
after) ORS=" "
---
$0="6"
NR="6"
NR%3="0"
before) ORS=" "
after) ORS="
"

Všimněte si, na kterých vstupních řádcích čísla (NR ) oddělovač výstupních záznamů (ORS). ) se stane novým řádkem (jako RS ) oproti prázdnému znaku (např. FS ).

Podrobnější způsob, jak napsat stejný kód, by byl:

$ cat tst.awk
{
    if (NR%3 == 0) {
        ORS = "\n"
    }
    else {
        ORS = " "
    }

    print
}

$ awk -f tst.awk file
1 2 3
4 5 6

a FYI správný (robustnější a jasnější) způsob, jak napsat stručný, idiomatický kód, o který jste se pokusili ve vaší otázce, by byl:

awk '{ORS=(NR%3?FS:RS)}1'

Závorky kolem trojky jsou v některých kontextech vyžadovány v některých awk a vždy zlepšují čitelnost, takže je vždy používejte. Původní kód se spoléhá na výsledek přiřazení k ORS, který vytváří nenulovou/nenulovou hodnotu, aby se jednalo o pravdivou podmínku, a tak vyvolá výchozí akci awks tisku aktuálního záznamu. Výsledek akce v tomto kontextu používejte pouze tehdy, když to POTŘEBUJETE, jinak vás jednoho dne kousne, když vaše data nebudou přesně taková, jak jste očekávali. Místo ponechání úkolu v bloku podmínky jsem ho přesunul do bloku akce a poté přidal konstantní pravdivou podmínku, 1 aby bylo zajištěno, že se každý záznam vytiskne bez ohledu na to, k čemu toto přiřazení vede.


Ne awk vysvětlení, protože již máte více než jednu dobrou odpověď, ale alternativy pro stejný úkol

$ seq 6 | xargs -n3
1 2 3
4 5 6

$ seq 6 | paste - - -
1       2       3
4       5       6

s paste výchozí oddělovač je tabulátor, který můžete změnit na mezeru pomocí -d' '

$ seq 6 | pr -3ats' '
1 2 3
4 5 6

Linux
  1. TCP Proxying pomocí socat

  2. Náhrada příkazů pomocí „?

  3. Příklady použití příkazu dmsetup v Linuxu

  1. Příklady příkazů awk v Linuxu

  2. awk:příkaz nenalezen

  3. Přesuňte složku v Linuxu pomocí příkazu mv

  1. Použití –exclude With The Du Command?

  2. 10 Praktické příklady použití příkazu scp

  3. Použití grep vs awk