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 10
trở 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 awk
mả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 BEGIN
khố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 ( \n
sẽ 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 " awk
kị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
}