GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Erklärung zum awk-Befehl mit ORS, NR, FS, RS

% ist der Modulo-Operator (siehe https://en.wikipedia.org/wiki/Modulo_operation) und NR%3?FS:RS ist ein ternärer Ausdruck (siehe https://en.wikipedia.org/wiki/%3F:). Dies sind beides gängige Konstrukte in vielen Programmiersprachen, sie sind nicht spezifisch für awk. Für die Bedeutung von ORS, NR, FS und RS siehe einfach diese awk-Manpage.

Führen Sie dies aus, um die Werte der Variablen im Code vor und nach dem auszuführenden Befehl anzuzeigen:

$ 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="
"

Beachten Sie, auf welchen Eingabezeilennummern (NR ) das Ausgabedatensatztrennzeichen (ORS ) wird zu einem Zeilenumbruch (wie RS ) gegen ein leeres Zeichen (wie FS ).

Eine ausführlichere Art, denselben Code zu schreiben, wäre:

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

    print
}

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

und zu Ihrer Information, der korrekte (robustere und klarere) Weg, den prägnanten, idiomatischen Code zu schreiben, der in Ihrer Frage versucht wird, wäre:

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

Die Klammern um die Ternäre werden in manchen Kontexten in einigen Fällen benötigt und verbessern immer die Lesbarkeit, also verwenden Sie sie einfach immer. Der ursprüngliche Code stützt sich auf das Ergebnis der Zuweisung an ORS, das einen Nicht-Null-/Nicht-Null-Wert erzeugt, damit es sich um eine wahre Bedingung handelt, und ruft so die awks-Standardaktion zum Drucken des aktuellen Datensatzes auf. Verwenden Sie das Ergebnis einer Aktion in diesem Kontext nur, wenn Sie es MÜSSEN, sonst wird es Sie eines Tages beißen, wenn Ihre Daten nicht genau das sind, was Sie erwartet haben. Anstatt die Zuweisung in einem Bedingungsblock zu belassen, habe ich sie in einen Aktionsblock verschoben und anschließend eine konstante wahre Bedingung hinzugefügt, 1 um sicherzustellen, dass jeder Datensatz gedruckt wird, unabhängig davon, was diese Zuweisung bewirkt.


Nicht die awk Erklärung, da Sie bereits mehr als eine gute Antwort, aber Alternativen für dieselbe Aufgabe haben

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

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

mit paste Standard-Trennzeichen ist ein Tabulator, den Sie mit -d' ' in ein Leerzeichen ändern können

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

Linux
  1. Verwendung von –exclude mit dem Du-Befehl?

  2. 10 praktische Beispiele für die Verwendung des scp-Befehls

  3. Beispiele für die Verwendung des Befehls dmsetup unter Linux

  4. awk-Befehlsbeispiele unter Linux

  5. awk:Befehl nicht gefunden

Linux-awk-Befehl mit 10 Beispielen

Eine einfache Erklärung des NAMEI-Befehls in Linux

Tutorial zur Verwendung des Timeout-Befehls unter Linux

Verwenden des Watch-Befehls unter Linux

AWK-Befehl unter Linux/Unix

Cut auf Linux Terminal verwenden