遍历存储在变量中的多行字符串


17

读到写这样的东西很不好,for line in $(command)相反,正确的方法似乎是:

command | while IFS= read -r line; do echo $line; done

这很好。但是,如果要迭代的是变量的内容而不是命令的直接结果,该怎么办?

例如,假设您创建以下文件quickfox

The quick brown
foxjumps\ over -
the
lazy ,
dog.

我希望能够做这样的事情:

# This is just for the example,
# I could of course stream the contents to `read`
variable=$(cat quickfox);
while IFS= read -r line < $variable; do echo $line; done; # this is incorrect

Answers:


19

在bash和zsh之类的现代shell中,您有一个非常有用的`<<<'重定向器,它接受字符串作为输入。所以你会做

while IFS= read -r line ; do echo $line; done <<< "$variable"

否则,您随时可以

echo "$variable" | while IFS= read -r line ; do echo $line; done

抱歉,我本该考虑回显课程的内容。但是还是感谢您的快速解答!
Sheljohn '16

1
使用时需要双引号$variable,否则while循环将仅获得一行输入。例如,请参见echo $variablevs echo "$variable"cat <<< $variablevs 之间的输出差异cat <<< "$variable"
cas

@cas实际上取决于$ variable中的内容。在OP提出的情况下(“ variable = $(cat quickfox)”),它可以工作而无需附加引号。但是对于一般情况,您是对的。我编辑我的答案。谢谢。
lgeorget

variable=$(cat quickfox)OP中的问题本身就提供什么,我在谈论的一个例子。$variable在双引号内使用该引号会包含换行符,而在不使用该双引号的情况下,shell会将换行符转换为空格。如果要逐行读取和处理,则差异很大-前者有多条输入线,而后者只有一条输入线。输入数据在表面上是相似的,但实际上在这两种情况下完全不同。
cas

例如:使用该输入数据,cat <<< "$variable" | wc -l返回5。 cat <<< $variable | wc -l返回1。如果要/需要在变量中保留空格(包括换行符,制表符,单个或多个空格),则在使用该变量时必须双引号,否则它们都将被转换为每个“单词”之间的单个空格。
cas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.