
Я прочитал несколько статей, в которых говорится о том, как заполнить массив Bash, где каждая запись имеет пробелы. Я думаю, что у меня это работает.
Мне нужно сделать это в цикле, заполняя больший массив содержимым всех массивов в каждой итерации.
Итак, у меня есть внешний цикл, перебирающий записи массива, который я получил из другого скрипта. В каждой итерации этого цикла я запускаю командную строку, которая выводит несколько строк, и я хочу, чтобы каждая строка была записью массива. Мне нужно добавить все эти записи массива в массив "summary". Поскольку я не знаю способа просто "добавить содержимое этого массива к другому массиву", я предполагаю, что мне нужно перебрать меньший массив. До сих пор это делало то, что мне нужно. Однако добавление к большему массиву, похоже, работает неправильно. После того, как я добавляю к большему массиву и проверяю длину большего массива, она всегда равна "1".
Соответствующая часть сценария примерно такая:
nslist=$(...)
pnarray=()
for ns in $nslist; do
IFS=$'\n' nspnarray=($(...))
echo "nspnarray.len[${#nspnarray[@]}]" # This looks fine
for pn in ${nspnarray[@]}; do
echo "pn[$pn]" # This looks fine
IFS=$'\n' pnarray+=$pn # Something wrong with this?
echo "pnarray.len[${#pnarray[@]}]" # is always 1
done
done
Это не полный скрипт, поэтому я надеюсь, что это понятно. Строки с комментариями "This looks fine" выводят то, что я хочу. В моих данных-образцах командная строка, которую я вызываю в назначении "nspnarray", выдает пять строк вывода, а оператор печати "nspnarray.len" показывает "5".
Затем я перебираю каждую из пяти записей, печатая каждую из них. Это все еще выглядит нормально. Оно печатает значение с пробелами, как и ожидалось. Затем я пытаюсь присвоить его моему массиву "summary", а затем печатаю длину массива summary, который всегда печатает "1". Я предполагаю, что я делаю что-то неправильно в назначении в строке "Something wrong with this?".
решение1
Добавление массива к другому массиву выполняется довольно просто:
$ a=(1 2 3)
$ b=(4 5 6)
$ a+=("${b[@]}")
$ typeset -p a
declare -a a=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")
Однако если вы делаете относительно сложные вещи с массивами, вам действительно следует использовать язык, более подходящий для этой задачи. awk
или perl
, например. Или python
. Или практически что угодно, кроме bash или других оболочек.
Оболочка хороша для организации выполнения других программ (и конвейеров других программ, и перенаправления stdin и stdout и т. д.) для выполнения чего-либо или обработки данных. Она не очень хороша в выполнении этих других задач сама по себе - на самом деле, она ужасна в этом.
awk
имеет многомерные массивы (как индексированные, так и ассоциативные), perl
делает тоже и также имеет структуры данных, где массивы или хэши могут содержать другие массивы и/или хэши, вложенные произвольно глубоко. Большинство других языков также имеют сложные структуры данных.
И, что не менее важно, у них нет проблем с цитированием или разделением слов, как у оболочек.