Сохраните выходные данные команды в массиве

Это приказ: pdc status -a 2>&1 | grep 'okay' Это дает следующий результат

[okay     ]: you are currently listening: 33[okay     ]: you are currently listening: 22[okay     ]: you are currently listening: 11

Я написал эту команду в файле сценария оболочки. Но я хочу сохранить выходные данные этой команды в массиве для некоторой обработки каждого значения индекса в массиве.

Как я могу сохранить выходные данные этой команды в массиве?

Если вам просто нужны цифры в конце каждой строки:

numbers=( $(pdc ... | grep -oP 'okay.+?\K\d+$') )

Если вы хотите сохранить каждую строку в массиве

mapfile -t lines < <(pdc ...)

Для извлечения данных из массивов:

for (( i=0; i<${#numbers[@]}; i++ )); do echo ${numbers[i]}; doneechoprintf "%s\n" "${lines[@]}"
332211[okay   ]: you are currently listening: 33[okay   ]: you are currently listening: 22[okay   ]: you are currently listening: 11

Прежде всего, вам не обязательно нужен массив, для обработки вывода построчно вы можете сделать:

pdc status -a 2>&1 | grep 'okay' | while read line; do somecommand "$line"; done

Если вам действительно нужен массив, Гленн Джекман уже отдал вы лучший способ сделать это, но вот другой подход:

#!/bin/bashIFS=$'\n'array=($(pdc status -a 2>&1 | grep 'okay'))

Объяснение:

  • $IFS=$'\n' : $IFS это баш разделитель полей ввода, установив для него только символ новой строки (\n) гарантирует, что ваши выходные строки не будут разделены пробелами, так что вы можете сохранить каждую строку как отдельный элемент массива. Без этого каждый слово из выходных данных вашей команды будет другой элемент.

    В зависимости от того, что вы хотите сделать, может быть хорошей идеей сохранить старое значение $IFS и восстановите его после считывания массива:

    oldifs="$IFS"IFS=$'\n'array=($(echo -e "foo bar\nbaz bar"))IFS="$oldifs"
  • $(command) : Это называется замена команд и позволяет сохранять выходные данные команды в переменной. Есть два способа сделать это:

    var=$(command)

    и

    var=`command`

    Из этих двух, самый $() лучше, потому что:

    • Он может работать с вложенными командами:

      var=$(command1 $(command 2))

      Например var=$(cat $(find ~/))

    • Он имеет гораздо меньше проблем с цитированием и приводит к более чистому синтаксису. Видеть здесь для большего.

Еще один более интуитивно понятный способ использования readarray встроенный (см. help -m readarray):

readarray -t array <<< "$(pdc status -a 2>&1 | grep 'okay')"

Далее, чтобы напечатать элемент массива, скажем, второй элемент, вы можете использовать:

echo "${array[1]}"

Чтобы напечатать все элементы массива в отдельных строках, вы можете использовать:

printf -- "%s\n" "${array[@]}"