【发布时间】:2012-08-10 12:59:35
【问题描述】:
我有一个多行的脚本变量。 我如何遍历这个变量来逐行读取并按照我想要的方式处理每一行?
【问题讨论】:
-
unix.stackexchange.com/questions/9784/…有类似问题;我已经在那里写了一个答案。
我有一个多行的脚本变量。 我如何遍历这个变量来逐行读取并按照我想要的方式处理每一行?
【问题讨论】:
考虑以下多行变量
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")
既不创建子shell(例如,您可以在循环中设置变量并在循环外部访问它们),并且都输出
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'
【讨论】:
$"a\nb\nc d e" 以在字符串中嵌入真正的换行符。 “-e”标志告诉echo 将“\n”作为新行处理,而不是两个单独的字符。
$ 对我来说是新的,但它适用于单引号 $'a\nb\nc d e'
gettext 翻译;单引号用于反斜杠扩展。
echo添加了一个尾随换行符时才有效;换句话说,它改变了要解析的变量。对于 OP,这可能会或可能不会接受。如果没有尾随换行符,read 将完全错过最后一行。详情请见unix.stackexchange.com/a/9789
虽然我通常使用“while read”来处理多行变量,但我最近有一个实例,它从文件中的每一行中删除了前导空格。使用它来解决我的问题:
printf '%s\n' "$var" | while IFS= read -r line
do
echo "$line"
done
代码取自this Unix Stack Exchange answer。
编辑:更新以修复 Nicolae Iotu 建议的最后一行问题
【讨论】:
printf '%s\n' "$var" ...