Индексы массива представляют собой целые числа или строки в кавычках awk. Здесь вы используете переменные, которые еще не были инициализированы. Поэтому их значения пусты.
Вы получаете последнее значение, назначенное массиву, потому что каждое назначение перезаписывает предыдущее значение. Использование print arr[""]также 10вернет вас .
Вместо этого используйте строки, как в arr["A"]=1.
Для вашей последней проблемы: Нет реальной возможности инициализировать awkмассив из командной строки, но вы можете передать «закодированное» значение, которое вы «декодируете» в своем BEGINблоке (например), чтобы извлечь ключи и значения для массива.
Пример, который передает специально разделенный список в виде одной строки и анализирует его для извлечения используемых индексов и значений:
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"]
}'
Используя отдельные ключи и значения:
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"]
}'
Это довольно ограниченный способ передачи «массива» awk, но он работает для простых значений, которые полностью контролируются. Примеры будут разбиты для любых данных, которые встраивают двоеточия (и знаки равенства для 1-го примера) в фактические данные.
Подобная передача данных также означает, что обратные слеши в данных должны обрабатываться особым образом ( \nбудет новой строкой \n, поэтому для передачи двухсимвольной строки вам придется использовать "\\\n"или '\\n').
Также связано:
Кроме того, вы можете написать «чистый awkсценарий», например так:
#!/usr/bin/awk -f
BEGIN {
# some initialisations
}
some_expression { some code }
END {
# more here
}