Tham chiếu các phần tử mảng theo chuỗi và khởi tạo mảng trong 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]
  }'

lệnh trên đưa ra giá trị đặt mới nhất cho arr['subscript'], trong trường hợp 10này là giá trị của arr[Q]trước đó printvà không phải 8là giá trị của arr[J].

Ngoài ra, giống như trong tập lệnh ở trên, tôi không muốn gán các giá trị cho arr['A'], arr['B'], arr['C'] and arr['E']cùng 1một dòng một giá trị , thay vào đó chuyển một mảng các chỉ mục dưới dạng một trong các tham số và giá trị chung như tham số khác cho một hàm xử lý logic của việc gán giá trị cho chúng.

Câu trả lời:


16

Các chỉ mục mảng là số nguyên hoặc chuỗi được trích dẫn trong awk. Những gì bạn đang làm ở đây là sử dụng các biến chưa được khởi tạo. Giá trị của họ là do đó trống rỗng.

Bạn nhận được giá trị mới nhất được gán cho mảng vì mỗi phép gán ghi đè giá trị trước đó. Sử dụng print arr[""]cũng sẽ cung cấp cho bạn 10trở lại.

Thay vào đó, sử dụng chuỗi, như trong arr["A"]=1.

Đối với vấn đề cuối cùng của bạn: Không có cơ sở thực sự nào để khởi tạo một awkmảng từ dòng lệnh, nhưng bạn có thể chuyển một giá trị "được mã hóa" mà bạn "giải mã" trong BEGINkhối của mình (ví dụ) để trích xuất các khóa và giá trị cho một mảng.

Ví dụ vượt qua một danh sách được phân tách đặc biệt dưới dạng một chuỗi và phân tích cú pháp để trích xuất các chỉ mục và giá trị sử dụng:

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"]
    }'

Sử dụng các khóa và giá trị riêng biệt:

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"]
    }'

Đây là một cách khá hạn chế để chuyển một "mảng" vào awk, nhưng nó hoạt động với các giá trị đơn giản mà người ta có toàn quyền kiểm soát. Các ví dụ sẽ phá vỡ mọi dữ liệu nhúng dấu hai chấm (và dấu bằng cho ví dụ thứ 1) trong dữ liệu thực tế.

Truyền dữ liệu như thế này cũng có nghĩa là dấu gạch chéo ngược trong dữ liệu sẽ phải được xử lý đặc biệt ( \nsẽ là một dòng mới, vì vậy để vượt qua hai chuỗi ký tự \n, bạn sẽ phải sử dụng "\\\n"hoặc '\\n').

Cũng liên quan:


Ở một bên, bạn có thể viết một " awkkịch bản thuần túy " như thế này:

#!/usr/bin/awk -f

BEGIN { 
   # some initialisations
}

some_expression { some code }

END {
    # more here
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.