Bash:"printf %q $str" 在脚本中删除空格。(替代方案?)

20
printf %q 应该对字符串进行引用。但是,当它在脚本中被执行时,会删除空格。
这个命令:
printf %q "hello world"

输出:

hello\ world

这是正确的。

这个脚本:

#!/bin/bash

str="hello world"
printf %q $str

输出:

helloworld

这是错误的。

如果确实期望这样的行为,那么在脚本中有哪些替代选择可以引用包含任何字符的字符串,以便被调用程序可以将其转换回原始形式?

谢谢。

软件:GNU bash,版本4.1.5(1)-release(i486-pc-linux-gnu)

编辑:已解决,谢谢。


4
将您的帖子标题中的“已解决”前缀删除。在StackOverflow.com上,您不应使用“已解决”前缀来标记问题已解决。您可以接受一个答案,或者发布您自己的答案并单击位于获得解决方案的答案附近投票按钮下面的勾选标志以接受它。 - Susam Pal
3个回答

46
你应该使用:

你应该使用:

printf %q "$str"

例子:

susam@nifty:~$ cat a.sh
#!/bin/bash

str="hello world"
printf %q "$str"
susam@nifty:~$ ./a.sh 
hello\ world
当你运行printf %q $str时,shell会将它展开为:
printf %q hello world

所以,字符串 helloworld 被作为两个独立的参数传递给 printf 命令,并将这两个参数并排打印。

但是当您运行 printf %q "$str" 时,shell 会将其展开为:

printf %q "hello world"
在这种情况下,字符串hello world作为单个参数提供给printf命令。这正是您想要的。 这里有些东西可供您尝试,以深入探讨这些概念:
susam@nifty:~$ showargs() { echo "COUNT: $#"; printf "ARG: %s\n" "$@"; }
susam@nifty:~$ showargs hello world
COUNT: 2
ARG: hello
ARG: world
susam@nifty:~$ showargs "hello world"
COUNT: 1
ARG: hello world
susam@nifty:~$ showargs "hello world" "bye world"
COUNT: 2
ARG: hello world
ARG: bye world
susam@nifty:~$ str="hello world"
susam@nifty:~$ showargs $str
COUNT: 2
ARG: hello
ARG: world
susam@nifty:~$ showargs "$str"
COUNT: 1
ARG: hello world

我在man页面中没有看到关于q作为有效格式参数的任何参考。有人能解释一下为什么%q有效吗?它是否已被弃用,现在有一个新的首选格式参数?我在man页面中没有看到任何描述此功能的内容。 - Anthony DiSanti
1
help printf 的输出中 - %q 以可重用为 shell 输入的方式引用参数 - Susam Pal
1
@AnthonyDiSanti,这是来自Bash的内容,你可以在Bash shell中找到man bashhelp printf。也许你正在查看man 1 printfman 3 printf%q不适用于它们。 - Gui Prá

2

这对我很有帮助。满足以下要求:

  1. 接受包含shell特殊字符的任意输入
  2. 不输出转义字符 "\"
#! /bin/bash
FOO='myTest3$; t%^&;frog now! and *()"'
FOO=`printf "%q" "$FOO"` # 含有 \ 字符 echo $FOO
# 去掉所有 \ 字符 FOO=$(printf "%q" "$FOO" | sed "s/\\\\//g") # 去掉 \ 字符
echo $FOO

所以,如果在转义命令之前回显$FOO,输出结果与您的最终回显完全相同。因此,看起来您正在取消转义已经转义的字符串,那么转义它的意义是什么?(至少在此处显示的上下文中) - Jon L.

1

尝试一下

printf %q "${str}"

在你的脚本中。


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