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

Read command is parsing multiline input

下面代码中的 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

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

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[@]}"

你可以这样做 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