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

20

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

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

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

    
задан Prakash V Holkar 25.03.2014 в 16:14
источник

3 ответа

21

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

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
    
ответ дан glenn jackman 25.03.2014 в 16:36
источник
19

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

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

Если вам нужен массив, Glenn Jackman уже дал вам лучший способ сделать это, но вот еще один подход:

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

Объяснение:

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

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

ответ дан terdon 25.03.2014 в 16:37
5

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

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

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

echo "${array[1]}"

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

printf -- "%s\n" "${array[@]}"
    
ответ дан Radu Rădeanu 25.03.2014 в 19:00