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


23

Это команда: 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

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

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

Ответы:


24

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

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

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

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

Чтобы извлечь данные из массивов:

for (( i=0; i<${#numbers[@]}; i++ )); do echo ${numbers[i]}; done
echo
printf "%s\n" "${lines[@]}"
33
22
11

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

1
Синтаксическая ошибка: перенаправление неожиданно, когда я используюmapfile -t array < <(grep.....)
Sachith Muhandiram

Вы используете Bash или другую оболочку?
Гленн Джекман

20

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

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

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

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

Объяснение:

  • $IFS=$'\n': $IFSэто разделитель входного поля bash , установка только на символ новой строки ( \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 ~/))

    • У него гораздо меньше проблем с цитированием и более чистый синтаксис. Смотрите здесь для получения дополнительной информации.


6

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

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

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

echo "${array[1]}"

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

printf -- "%s\n" "${array[@]}"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.