Referensi elemen array dengan string, dan inisialisasi array dalam awk

8
#!/usr/bin/env bash
awk '
  BEGIN {
    arr[A]=1;
    arr[B]=1;
    arr[C]=1;
    arr[E]=1;
    arr[J]=8;
    arr[Q]=10;
    print arr[J]
  }'

perintah di atas menampilkan nilai set terbaru untuk arr['subscript'], dalam hal ini 10adalah nilai arr[Q]sebelum printdan bukan 8itu adalah nilai arr[J].

Juga, seperti dalam skrip di atas, saya tidak ingin menetapkan nilai arr['A'], arr['B'], arr['C'] and arr['E']yang memiliki nilai yang sama 1satu baris pada satu waktu, alih-alih memberikan larik langganan sebagai salah satu parameter dan nilai umum sebagai parameter lain ke fungsi yang menangani logika memberi mereka nilai.

HarshvardhanSharma
sumber

Jawaban:

16

Indeks array adalah bilangan bulat atau string yang dikutip dalam awk. Apa yang Anda lakukan di sini menggunakan variabel yang belum diinisialisasi. Nilai-nilai mereka karenanya kosong.

Anda mendapatkan nilai terbaru yang ditetapkan ke array karena setiap tugas menimpa nilai sebelumnya. Menggunakan print arr[""]juga akan memberi Anda 10kembali.

Sebagai gantinya, gunakan string, seperti pada arr["A"]=1.

Untuk masalah terakhir Anda: Tidak ada fasilitas nyata untuk menginisialisasi awkarray dari baris perintah, tetapi Anda dapat memberikan nilai "yang dikodekan" yang Anda "decode" di BEGINblok Anda (misalnya) untuk mengekstrak kunci dan nilai-nilai untuk array.

Contoh yang melewati daftar terbatas khusus sebagai string tunggal dan mem-parsingnya untuk mengekstrak indeks dan nilai yang akan digunakan:

awk -v vals="A=1:B=1:C=1:E=1:J=8:Q=10" '
    BEGIN {
        n = split(vals, v, ":")
        for (i = 1; i <= n; ++i) {
            split(v[i], a, "=")
            arr[a[1]] = a[2]
        }

        print arr["J"]
    }'

Menggunakan kunci dan nilai yang terpisah:

awk -v keys="A:B:C:E:J:Q" -v vals="1:1:1:1:8:10" '
    BEGIN {
        nk = split(keys, k, ":")
        nv = split(vals, v, ":")

        if (nk != nv) exit 1

        for (i = 1; i <= nk; ++i)
            arr[k[i]] = v[i]

        print arr["J"]
    }'

Ini adalah cara yang sangat terbatas untuk mengirimkan "array" ke awkdalamnya, tetapi ia bekerja untuk nilai-nilai sederhana yang dapat dikontrol sepenuhnya oleh seseorang. Contoh-contoh akan pecah untuk setiap data yang menyematkan titik dua (dan tanda sama dengan untuk contoh 1) dalam data aktual.

Melewati data seperti ini juga berarti garis miring terbalik pada data harus diperlakukan secara khusus ( \nakan menjadi baris baru, jadi untuk melewatkan dua karakter string \n, Anda harus menggunakan "\\\n"atau '\\n').

Juga terkait:


Sebagai tambahan, Anda dapat menulis " awkskrip murni " seperti ini:

#!/usr/bin/awk -f

BEGIN { 
   # some initialisations
}

some_expression { some code }

END {
    # more here
}
Kusalananda
sumber