首页 > 解决方案 > 使用参数扩展字符串替换的换行符的 printf 解释

问题描述

我有一个字符串:string="foo=bar boo=far rab=oof raf=oob"

我想用换行符替换字符串中的所有空格:string=${string// /$"\n"}

当我使用printf时,bash 打印:

~$ printf "%s" "$string"
foo=bar\nboo=far\nrab=oof\nraf=oob

但是,当我将命令输入错误时printf %s""$string,我得到:

~$ printf %s""$string
foo=bar
boo=far
rab=oof
raf=oob

有什么区别printf "%s" "$string"并且只会解释其中一个命令中的换行符printf %s""$stringprintf

标签: stringbashshellparameter-expansion

解决方案


$"\n"查找\n当前语言环境中的翻译,但由于没有找到任何内容,所以它只是返回\n(有关详细信息,请参阅如何向 bash 脚本添加本地化支持 (BashFAQ/098))。

  1. printf %s "$string"(不需要 %s 周围的引号)获取 $string 的内容并按原样打印。

  2. printf %s""$string将 %s 与空字符串和变量的内容连接起来。\n因此进入模板并被解释为换行符。

您可以使用set -xv使 shell 向您展示它如何解释命令和变量。

从不安全的字符串创建 printf 模板是危险的。我会推荐一种不同的方式:

s=${string// /$'\n'}
printf %s "$s"

扩展为真正的$'\n'换行符,因此 $s 将包含实际的换行符。然后就可以直接打印了。

另一种方法是

printf '%s\n' $string

不改变 $string 的值。未引用的字符串会进行单词拆分,并且每个结果单词都使用添加换行符的模板打印。


推荐阅读