У меня есть команда, возвращающая несколько строк. Для дальнейшей обработки мне нужно обработать каждую строку этих строк.
Мой текущий код работает путем изменения IFS ( Разделитель внутренних полей ):
ROWS=$(some command returning multiple lines)
O=$IFS #save original IFS
IFS=$(echo -en "\n\b") # set IFS to linebreak
for ROW in ${ROWS[@]}
do
echo "$ROW"
done
IFS=$O #restore old IFS
Мне интересно, есть ли лучший способ получить доступ к отдельным строкам вывода нескольких строк, один без изменения IFS? Особенно читаемость моего сценария ухудшается при модификации IFS.
Обновление: у меня проблемы с получением ответов, например, от Чороба:
while IFS= read -r line ; do
let var+=line #line 42
done << $(sqlite3 -list -nullvalue NULL -separator ',' /var/log/asterisk/master.db "${QUERY}")
echo "$var" # line 44
дает мне
./bla.sh: row 44: Warning: here-document at line 43 delimited by end-of-file (wanted `$(sqlite3 -list -nullvalue NULL -separator , /var/log/asterisk/master.db ${QUERY})')
./bla.sh: row 42: let: echo "": syntax error: invalid arithmetic operator. (error causing character is \"""\").
Кто-нибудь может мне помочь с этим? Спасибо!
bash
shell
command
command-substitution
stefan.at.wpf
источник
источник
< <(some command returning multiple lines)
, но это не то, что вы делаете.Ответы:
Как насчет
read
вwhile
цикле?Однако будьте осторожны, так как канал запускается в подоболочке, что означает, что вы не можете изменять значения переменных для остальной части сценария. Если вам нужно что-то, чтобы выжить из цикла while, вы можете использовать замену процесса в bash:
источник
bash
, но стоит отметить, что определение переменных в скорлупе является лишь проблемойbash
, так как выполнение того же действияzsh
вообще не будет иметь этой проблемы.Установка
IFS
только новой строки недостаточно. (Кстати, почему вы тоже разделяете символы возврата на задний план?)В вашем коде
${ROWS[@]}
(что странно писать$ROWS
-ROWS
это не массив) не стоит заключать в двойные кавычки. (Если бы он был внутри двойных кавычек, вы бы получили одну строку, посколькуROWS
это не массив.) Таким образом, оболочка разбивает значение переменной на поля в каждомIFS
символе, а затем обрабатывает каждое поле как шаблон глобуса. Например, если одна из строк, напечатанных командой, содержит один символ*
, он будет заменен именами файлов в текущем каталоге.Вы можете отключить с помощью
set -f
. В большинстве случаев, когда выIFS
используете функцию разделения поля оболочки, вам также необходимо отключить глобализацию. Установите его обратно с помощьюset +f
.Надежная идиома для чтения выходных данных команды построчно
while IFS= read -r
.Обратите внимание, что большинство оболочек запускают каждую команду конвейера в отдельной подоболочке. Поэтому, если вам нужно установить переменные и использовать их после цикла, оберните эти команды в группу вместе с циклом. (Ksh и zsh - исключения, они запускают последнюю команду конвейера в родительской оболочке.)
источник
Вы смешиваете синтаксис here-document и here-string в своем вопросе об обновлении.
Либо используйте здесь-документ:
Или вот строчка:
источник