【问题标题】:Read line by line from a variable in shell scripting从 shell 脚本中的变量逐行读取
【发布时间】:2012-08-10 12:59:35
【问题描述】:

我有一个多行的脚本变量。 我如何遍历这个变量来逐行读取并按照我想要的方式处理每一行?

【问题讨论】:

标签: bash shell


【解决方案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")

既不创建子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's excellent Bash FAQ

【讨论】:

  • 这是一个完美的解决方案,只是好奇,为什么不只是 x="a\nb\nc d e"?
  • @SenthilKumar,该字符串包含 10 个字符:'a'、'\'、'n'、'b' 等。“\n”在双引号内并不特殊。在 bash 中,可以编写 $"a\nb\nc d e" 以在字符串中嵌入真正的换行符。 “-e”标志告诉echo 将“\n”作为新行处理,而不是两个单独的字符。
  • @chepner: thx, $ 对我来说是新的,但它适用于单引号 $'a\nb\nc d e'
  • @Karoly:我的错误,我使用了错误的引号。双引号用于gettext 翻译;单引号用于反斜杠扩展。
  • 应该提到,这个解决方案只有在echo添加了一个尾随换行符时才有效;换句话说,它改变了要解析的变量。对于 OP,这可能会或可能不会接受。如果没有尾随换行符,read 将完全错过最后一行。详情请见unix.stackexchange.com/a/9789
【解决方案2】:

虽然我通常使用“while read”来处理多行变量,但我最近有一个实例,它从文件中的每一行中删除了前导空格。使用它来解决我的问题:

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

代码取自this Unix Stack Exchange answer

编辑:更新以修复 Nicolae Iotu 建议的最后一行问题

【讨论】:

  • 不错的解决方案,但您需要以新行结束 printf 以使其处理最后一行:printf '%s\n' "$var" ...
  • 好点,谢谢。我已根据您建议的更改更新了我的答案。
猜你喜欢
  • 2021-06-02
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
  • 2021-11-24
  • 2018-04-12
  • 1970-01-01
  • 1970-01-01
  • 2019-08-14
相关资源
最近更新 更多