我有一个多行的脚本变量。 如何遍历这个变量以逐行读取并根据我的需求处理每一行?
考虑以下多行变量:
x=$(echo -e "a\nb\nc d e")
对于每一行,可以采用一个简单的过程:在行前加上前缀=LINE:
,并且使用单引号将该行括起来,然后以echo
的方式输出即可。以下两行代码均满足此要求:
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'
详细内容请参考 Greg Wooledge 的精彩 Bash FAQ。
$"a\nb\nc d e"
来嵌入真正的换行符。 "-e"标志告诉echo
将"\n"处理为新行,而不是两个单独的字符。 - chepner$
对我来说是新的,但它可以与单引号一起使用$'a\nb\nc d e'
。 - Karoly Horvathgettext
翻译;单引号用于反斜杠扩展。 - chepnerecho
会添加一个尾随换行符;换句话说,它会改变要解析的变量。这可能或可能不被OP接受。如果没有尾随换行符,read
将完全错过最后一行。有关详细信息,请参见https://unix.stackexchange.com/a/9789。 - Binarus尽管我通常使用“while read”处理多行变量,但最近有一个实例,在文件中每行开头的空格被删除了。使用以下代码可以解决这个问题:
printf '%s\n' "$var" | while IFS= read -r line
do
echo "$line"
done
编辑:根据Nicolae Iotu的建议更新,以解决最后一行问题。
printf '%s\n' "$var" ...
- Nicolae Iotu