我在 Ubuntu 20.04 上使用 Bash 5.0.17
当我运行以下命令时:
IFS=":"; for i in "1:2:3"; do echo $i; done
# output is: 1 2 3
IFS=":"; for i in "1:2:3"; do echo "$i"; done
output is: 1:2:3
IFS=":"; for i in "1:2:3"; do printf "%s\n" $i; done
# output is:
# 1
# 2
# 3
IFS=":"; for i in "1:2:3"; do printf "%s\n" "$i"; done
# output is: 1:2:3
这让我很困惑。
- 为什么不将
echo
每个标记打印在单独的行中? - 为什么在没有引用的情况下却能
printf
按预期工作?$i
- 为什么引用时
echo
and都会失败?printf
$i
我感谢您的帮助
答案1
循环for i in "1:2:3"; do ...
只运行一次。静态文字字符串没有分词,只有扩展,甚至只有不带引号的扩展。你会看到不同的结果,例如
IFS=:
var="1:2:3"
for i in $var; do...
剩下的就是如何echo
和printf
工作。echo
用空格连接参数,并打印连接后的字符串,后跟一个换行符。但printf
根据需要多次重复格式字符串以容纳所有参数,因此您会得到多个换行符。
因此,在第一个中,echo $i
运行 i
设置为1:2:3
。扩展未加引号,因此将其拆分,并echo
获取三个参数1
, 2
, 3
。它将它们与空格连接起来,给出1 2 3
,输出是加上换行符。这和跑步是一样的echo 1 2 3
。 (甚至是echo 1 2 "3"
,因为 shell 命令行上未加引号的空格数量并不重要。)
第三个与 类似printf "%s\n" 1 2 3
,并且重复格式字符串,输出分三行。类似的东西printf "%s %s\n" 1 2 3
每次重复都会使用两个参数,并会1 2
在一行和3
另一行上打印。