GNU/Linux >> Belajar Linux >  >> Linux

Penjelasan tentang perintah awk menggunakan ORS, NR, FS, RS

% adalah operator modulo (lihat https://en.wikipedia.org/wiki/Modulo_operation) dan NR%3?FS:RS adalah ekspresi ternary (lihat https://en.wikipedia.org/wiki/%3F:). Keduanya adalah konstruksi umum dalam banyak bahasa pemrograman, keduanya tidak spesifik untuk awk. Untuk arti ORS, NR, FS, dan RS lihat saja halaman manual awk itu.

Jalankan ini untuk melihat nilai variabel dalam kode sebelum dan sesudah perintah yang Anda jalankan:

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

Perhatikan nomor baris masukan mana (NR ) Pemisah Catatan Keluaran (ORS ) menjadi baris baru (seperti RS ) vs char kosong (seperti FS ).

Cara yang lebih bertele-tele untuk menulis kode yang sama adalah:

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

    print
}

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

dan FYI cara yang benar (lebih kuat dan lebih jelas) untuk menulis kode singkat dan idiomatis yang dicoba dalam pertanyaan Anda adalah:

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

Parens di sekitar ternary diperlukan dalam beberapa awk dalam beberapa konteks dan selalu meningkatkan keterbacaan jadi selalu gunakan saja. Kode asli bergantung pada hasil penugasan ke ORS yang menghasilkan nilai bukan nol/bukan nol agar menjadi kondisi yang benar dan dengan demikian memanggil tindakan default awks untuk mencetak catatan saat ini. Hanya gunakan hasil tindakan dalam konteks itu ketika Anda PERLU jika tidak, itu akan menggigit Anda suatu hari ketika data Anda tidak persis seperti yang Anda harapkan. Alih-alih meninggalkan tugas dalam blok kondisi, saya memindahkannya ke blok tindakan dan kemudian menambahkan kondisi benar yang konstan setelahnya, 1 untuk memastikan setiap rekaman dicetak terlepas dari hasil tugas tersebut.


Bukan awk penjelasan karena Anda sudah memiliki lebih dari satu jawaban yang bagus, tetapi alternatif untuk tugas yang sama

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

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

dengan paste pembatas default adalah tab, yang dapat Anda ubah ke spasi dengan -d' '

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

Linux
  1. 10 Contoh Praktis Menggunakan Perintah scp

  2. Contoh penggunaan perintah dmsetup di Linux

  3. Menggunakan grep vs awk

  1. Substitusi Perintah Menggunakan “?

  2. Menggunakan –exclude Dengan Perintah Du?

  3. Menggunakan Perintah ripgrep (rg) di Linux

  1. Proksi TCP menggunakan socat

  2. Contoh Perintah awk di Linux

  3. awk:perintah tidak ditemukan