如何在bash printf中转义一系列反斜杠?

18
以下脚本产生了意外的输出:
printf "escaped slash: \\ \n"
printf "2 escaped slashes: \\\\ \n"
printf "3 escaped slashes: \\\\\\ \n"
printf "4 escaped slashes: \\\\\\\\ \n"

在 Ubuntu 14 下作为 bash 脚本运行,我看到:

escaped slash: \
2 escaped slashes: \ 
3 escaped slashes: \\ 
4 escaped slashes: \\

嗯... 什么?

3个回答

13

假设 printfFORMAT 字符串被双引号包围,与例如 echo(两者都是Shell内置命令)相比,printf 需要进行额外一层的展开。

实际上,你期望从 printf 中得到的结果,可以通过使用单引号来实现:

printf '1 escaped slash:   \\ \n'
printf '2 escaped slashes: \\\\ \n'
printf '3 escaped slashes: \\\\\\ \n'
printf '4 escaped slashes: \\\\\\\\ \n'

输出:

1 escaped slash:   \
2 escaped slashes: \\
3 escaped slashes: \\\
4 escaped slashes: \\\\

请注意,这是有效的,因为您防止 bashprintf 看到参数之前删除任何反斜杠。 - chepner
@chepner:我同意。似乎评估的顺序是:1)bash扩展FORMAT字符串(仅当用双引号括起来时!)。2)printfARGUMENTSFORMAT组合成一个字符串。3)最终字符串再次扩展(即\变为\)。4)结果最终被打印出来。 - Eugeniu Rosca
关闭;“printf”仅处理插入参数之前的“FORMAT”;将“printf'\n'”与“printf'%s''\n'”进行比较。 - chepner

6

printf是bash内置命令。查看help printf

printf [-v var] format [arguments]
      根据格式控制,格式化并打印ARGUMENTS。

你需要传递格式和参数。因此在参数之前添加格式"%s\n"

printf "%s\n" "escaped slash: \\"
printf "%s\n" "2 escaped slashes: \\\\"
printf "%s\n" "3 escaped slashes: \\\\\\"
printf "%s\n" "4 escaped slashes: \\\\\\\\"

输出:

转义斜杠:\ 
两个转义斜杠:\\ 
三个转义斜杠:\\\ 
四个转义斜杠:\\\\ 

@Yuri G.:感谢您提供额外的描述。 - Cyrus
请注意,这是有效的,因为您避免了 printf 对反斜杠进行另一轮解释。 - chepner

2

关于Cyrus所说的另外一点注意事项:

如果你用单引号引用printf函数中的ARGUMENT,那么你可以省略很多反斜杠。例如:

printf "%s\n" 'escaped slash: \'
printf "%s\n" '2 escaped slashes: \\'
printf "%s\n" '3 escaped slashes: \\\'
printf "%s\n" '4 escaped slashes: \\\\'

输出

1 escaped slash:   \
2 escaped slashes: \\
3 escaped slashes: \\\
4 escaped slashes: \\\\

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接