以下代码中的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
以上代码有什么问题?如何纠正它以获得预期的输出?
答案 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