读取命令正在解析多行输入

时间:2018-07-30 14:03:41

标签: bash shell parsing newline ifs

以下代码中的read命令仅解析输入的第一行。但是,当IFS设置为逗号或换行符以外的其他任何符号时,效果很好。

u="*
john
dan"

IFS=$'\n';read -ra q <<< "$u"

for j in "${q[@]}"
do
    echo "drop user $j"
done

输出为:

drop user *

我期望的是:

drop user *
drop user john
drop user dan

请注意,输入中的第一项是星号。因此,如果我使用以下代码进行拆分,则星号将扩展到目录中的文件列表。

IFS=$'\n'; q=($u); unset IFS;

输出:

drop user abc
drop user test.sh
drop user john
drop user dan

以上代码有什么问题?如何纠正它以获得预期的输出?

2 个答案:

答案 0 :(得分:3)

read仅从标准输入中读取一行。如果您具有Bash 4.0或更高版本,则可以使用readarray

readarray -t q <<< "$u"

之后,您的数组如下所示:

$ declare -p q
declare -a q=([0]="*" [1]="john" [2]="dan")

readarray(及其别名mapfile)默认使用换行符分隔数组元素,因此可以删除IFS赋值。 Bash 4.4引入了-d选项,以使用除换行符以外的定界符,但这不是必需的。

一旦元素位于数组中,就可以使用单个printf语句来打印命令,如下所示:

printf 'drop user %s\n' "${q[@]}"

答案 1 :(得分:3)

您可以执行以下while read循环:

u="*
john
dan"
while IFS= read -r user; do
    echo "drop user $user"
done <<< "$u"

输出:

drop user *
drop user john
drop user dan