Читайте построчно и присвойте каждой строке свою переменную в Bash - PullRequest
1 голос
/ 11 апреля 2020

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

my_program | {
    read -r foo
    read -r bar
    read -r baz
}

Кажется, что я могу получить доступ только к этим переменным внутри блока, но я не хочу помещать все внутри блока.

Я также пытался использовать опцию -d с символом, который вряд ли будет отображаться в выводе в качестве аргумента.

IFS=$'\n' read -r -d$'\a' foo bar baz < <(my_program)

Кажется, что работает, за исключением того, что если есть более 3 строк, переменная 'baz' получает третью строку и все лишние строки. На самом деле это не проблема, поскольку я знаю точное количество строк, которые будет выводить моя программа.

Интересно, есть ли лучший способ сделать это.

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Вот мое мнение об этом.

#!/usr/bin/env bash

i=0
n=3

while (( i < n )); do
  read -r first
  read -r second
  read -r third
  (( i++ )) || break
done < <(printf '%s\n' one two three four five six)

printf '%s\n' "$first" "$second" "$third"
  • В вашем случае замените printf на my_program
  • Также рассмотрите возможность использования массива, подобного тому, что было предложено в комментарии @ogus ismail.

Использование mapfile aka readarray

mapfile -t -n 3 array < <(printf '%s\n' one two three four five six)

Всего array

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

Вывод

one
two
three

Индекс начинается с нуля

printf '%s\n' "${array[0]}" "${array[1]}" "${array[2]}"

Выход

one
two
three
0 голосов
/ 12 апреля 2020

Глупый я. Я только что понял, что могу читать строки в массив, а затем назначать каждому элементу массива описательное имя.

mapfile -t arr < <(my_program)
foo=${arr[0]}
bar=${arr[1]}
baz=${arr[2]}

Я объяснил, почему я не хочу использовать массив в своих комментариях к вопрос и принятый ответ. Эти переменные на самом деле являются параметрами конфигурации, поэтому я определенно не хочу ссылаться на VIRTUAL_IP с чем-то вроде ${arr[0]}.

...