Чтение строки за строкой из переменной в сценариях оболочки

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

Ответ 1

Рассмотрим следующую многострочную переменную

x=$(echo -e "a\nb\nc d e")

и простой процесс для каждой строки: просто echo с префиксом = LINE: и одинарными кавычками вокруг строки. Любой из следующих кодов удовлетворит это требование:

while read line; do echo "LINE: '${line}'"; done <<< "$x"

или

while read line; do echo "LINE: '${line}'"; done < <(echo "$x")

Ни один из них не создает подоболочку (так что вы можете, например, устанавливать переменные в цикле и получать к ним доступ вне его), и оба вывода

LINE: 'a'
LINE: 'b'
LINE: 'c d e'

Но предположим, что вместо этого у вас есть

x=$(echo -e "a \n b\nc d e")
# note--------^--^

и что начальные и конечные пробелы важны для вашего приложения (например, анализ Git-фарфора). Оба приведенных выше кода будут давать точно такой же вывод для последней переменной/данных, что и для первой, что не является тем, что вам нужно. Чтобы сохранить начальные и конечные пробелы, замените while read line на while IFS= read -r line. Т.е. любой из следующих кодов

while IFS= read -r line; do echo "LINE: '${line}'"; done <<< "$x"

или

while IFS= read -r line; do echo "LINE: '${line}'"; done < <(echo "$x")

произведет

LINE: 'a '
LINE: ' b'
LINE: 'c d e'

Подробности смотрите в Greg Wooledge - превосходном Bash FAQ.

Ответ 2

Хотя я обычно использую "while read" для обработки многострочных переменных, у меня недавно был экземпляр, где он удалял ведущее пространство из каждой строки в файле. Исправлена ​​проблема с этим:

printf %s "$var" | while IFS= read -r line
do
   echo "$line"
done

Код, взятый из этот ответ Exchange Unix Stack.