Здесь меня бросают в глаза две проблемы:
Вы не указали свои переменные в кавычках, поэтому оболочка потенциально искажает значения. Я дам вам альтернативное предложение для вашего скрипта, основанное на удалении пробелов .
Вы обрабатываете XML с помощью регулярных выражений. Это будет работать сейчас, но имейте в виду, что в будущем это может сломаться, когда что-то неожиданное изменится.
Следующий код
#!/bin/bash
# ...
# Not even going to attempt to reduce this without seeing your XML
url=$(grep -E -m 1 -o "(.*) " costa_export.xml| sed -e 's,.*\([^<]*\) .*,\1,g')
# Debug
echo "raw: $url" >&2
# Strip leading and trailing whitespace
url="${url#"${url%%[![:space:]]*}"}" # remove leading whitespace
url="${url%"${url##*[![:space:]]}"}" # remove trailing whitespace
# More debug
echo "now: $url" >&2
# Save the URL
echo -n "$url" > url.txt
# Retrieve the URL contents
wget -O price.zip "$url"
Индексы массива представляют собой либо целые числа, либо строки в кавычках в 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
}