带参数扩展字符串替换的换行符的 printf 解释
printf interpretation of newline characters with parameter expansion string replacement
我有一个字符串:string="foo=bar boo=far rab=oof raf=oob"
我想用换行符替换字符串中的所有白色-space: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""$string
有什么区别 printf
只会解释其中一个命令中的换行符?
$"\n"
在当前语言环境中查找 \n
的翻译,但由于没有找到任何内容,它只是 returns \n
(请参阅 How to add localization support to your bash scripts (BashFAQ/098) 了解详情)。
printf %s "$string"
(不需要 %s 周围的引号)获取 $string 的内容并按原样打印。
printf %s""$string
将 %s 与空字符串和变量的内容连接起来。 \n
因此进入模板并被解释为换行符。
您可以使用 set -xv
让 shell 向您展示它如何解释命令和变量。
从不安全的字符串创建 printf 模板是危险的。
我推荐一种不同的方式:
s=${string// /$'\n'}
printf %s "$s"
$'\n'
扩展为一个真正的换行符,因此 $s 将包含实际的换行符。然后就可以直接打印了。
另一种方式是
printf '%s\n' $string
不改变 $string 的值。不带引号的字符串进行单词拆分,每个生成的单词都使用向其添加换行符的模板打印。
根据 bash 联机帮助页,您不是用换行符替换,而是用反斜杠和 n 个字符替换:
A double-quoted string preceded by a dollar sign ($"string") will cause the string to be translated according to the current locale. If the current locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted.
(我怀疑您反而想使用 $'' 和两个单引号。)
printf 命令将“\n”解释为换行符的转义序列,但仅在第一个参数中,这就是您的命令中发生的情况:
printf %s""$string
我有一个字符串:string="foo=bar boo=far rab=oof raf=oob"
我想用换行符替换字符串中的所有白色-space: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""$string
有什么区别 printf
只会解释其中一个命令中的换行符?
$"\n"
在当前语言环境中查找 \n
的翻译,但由于没有找到任何内容,它只是 returns \n
(请参阅 How to add localization support to your bash scripts (BashFAQ/098) 了解详情)。
printf %s "$string"
(不需要 %s 周围的引号)获取 $string 的内容并按原样打印。printf %s""$string
将 %s 与空字符串和变量的内容连接起来。\n
因此进入模板并被解释为换行符。
您可以使用 set -xv
让 shell 向您展示它如何解释命令和变量。
从不安全的字符串创建 printf 模板是危险的。 我推荐一种不同的方式:
s=${string// /$'\n'}
printf %s "$s"
$'\n'
扩展为一个真正的换行符,因此 $s 将包含实际的换行符。然后就可以直接打印了。
另一种方式是
printf '%s\n' $string
不改变 $string 的值。不带引号的字符串进行单词拆分,每个生成的单词都使用向其添加换行符的模板打印。
根据 bash 联机帮助页,您不是用换行符替换,而是用反斜杠和 n 个字符替换:
A double-quoted string preceded by a dollar sign ($"string") will cause the string to be translated according to the current locale. If the current locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted.
(我怀疑您反而想使用 $'' 和两个单引号。)
printf 命令将“\n”解释为换行符的转义序列,但仅在第一个参数中,这就是您的命令中发生的情况:
printf %s""$string