为什么不是';t sed';在bash中存储的输出及其多个反斜杠?
我试图将sed的输出存储到一个变量中,但是输出与我期望的不同 我的测试如下为什么不是';t sed';在bash中存储的输出及其多个反斜杠?,bash,sed,output,backslash,Bash,Sed,Output,Backslash,我试图将sed的输出存储到一个变量中,但是输出与我期望的不同 我的测试如下 $ foo="this is (foo)" $ x="$(sed 's/(/\\\\(/g' <<< $foo)" 我得到的结果是: $ echo $x this is \(foo) 但是,当我没有将输出分配给变量时,结果就是预期的结果: $ sed 's/(/\\\\(/g' <<< $foo this is \\(foo) $sed's/(/\\\\(/g'不要信任echo:
$ foo="this is (foo)"
$ x="$(sed 's/(/\\\\(/g' <<< $foo)"
我得到的结果是:
$ echo $x
this is \(foo)
但是,当我没有将输出分配给变量时,结果就是预期的结果:
$ sed 's/(/\\\\(/g' <<< $foo
this is \\(foo)
$sed's/(/\\\\(/g'不要信任echo
:POSIX规范在其实现中留下了足够的余地,您无法信任其输出来正确表示手头的值。相反,请使用printf
:
foo="this is (foo)"
x="$(sed 's/(/\\\\(/g' <<<"$foo")"
printf '%s\n' "$x"
从中,强调补充道:
应支持以下操作数:
串
要写入标准输出的字符串。如果第一个操作数是-n
,或者任何操作数包含反斜杠('\')字符,则结果由实现定义
同样,从同一文档的应用程序使用部分:
除非省略了-n
(作为第一个参数)和转义序列,否则不可能在所有POSIX系统中使用echo可移植
printf
实用程序可移植地用于模拟echo实用程序的任何传统行为[…]
不要信任echo
:POSIX规范在其实现中留下了足够的余地,您无法信任其输出来正确表示手头的值。相反,请使用printf
:
foo="this is (foo)"
x="$(sed 's/(/\\\\(/g' <<<"$foo")"
printf '%s\n' "$x"
从中,强调补充道:
应支持以下操作数:
串
要写入标准输出的字符串。如果第一个操作数是-n
,或者任何操作数包含反斜杠('\')字符,则结果由实现定义
同样,从同一文档的应用程序使用部分:
除非省略了-n
(作为第一个参数)和转义序列,否则不可能在所有POSIX系统中使用echo可移植
printf
实用程序可移植地用于模拟echo实用程序的任何传统行为[…]
顺便说一句,反斜杠会消耗你的文字反斜杠,所以对于那些(但不是$(…)
),你有一个额外的失败模式。这不是回答你的问题(因此有一个注释;),但我喜欢为sed测试做的是[vim]diff-infle,这是一种有趣的方式:)引用你的变量(“$x”
,而不是$x
),除非您有非常具体的理由不完全理解您通过不这样做调用的行为。顺便说一句,反勾号将消耗您的文字反斜杠,因此对于那些(但不是$(…)
),您有一个额外的故障模式。这并不是回答您的问题(因此有一个注释;),但是我喜欢为sed测试做的是[vim]diff-infle,这是一种有趣的方式:)引用变量(“$x”
,而不是$x
),除非您有非常具体的理由不这样做,并且不完全理解您正在调用的行为。因此,我想,没有更多的echo
用于调试。。。谢谢其他函数(如scp
)的错误输出(STDERR
)不显示额外的反斜杠,这正常吗?scp
是一种特殊情况,因为它通过远程端上的部分shell扩展传递来运行远程文件名。委婉地说,这不是一个好的做法,但在不做大量额外工作的情况下远程进行通配符扩展是必要的……因此,对于大多数以比scp
更好/更合理的方式实现的命令来说,这将是不正常的,但具体情况是另一个问题。顺便说一句,关于调试,请使用set-x
,或者bash-xyourscript
;这将为您提供在stderr上引用的命令shell——无论如何,它比echo
有用得多;你无法区分echo“foo-bar”
和echo-foo-bar
之间的区别,这种区别是巨大而重要的!您还可以使用类似于PS4=':$LINENO+'
和set-x
的方法来打印每个命令执行时的行号。(另一方面,printf“%q”
是另一个有用的工具,可以放在你的武器库中——使用ksh或bash之类的派生工具,它对引用的输入进行求值,从而使其eval
安全……不过避免任何数据在shell中被解析为代码的情况,总比使用反斜杠或其他方式转义要好解析是安全的,如果确实需要转义,最好知道如何正确地进行)。因此,我想调试时不再使用echo
,谢谢!那么这比其他函数(例如scp
)的错误输出(STDERR
)正常吗不显示额外的反斜杠?scp
是一种特殊情况,因为它通过远程端上的部分外壳扩展过程来运行远程文件名。说得委婉一点,这不是一种好的做法,但需要在不做大量额外工作的情况下远程进行通配符扩展……因此,对于大多数命令,在n比scp
更好/更明智的方法,这可能是不正常的,但具体情况是不同的。顺便说一句,re:调试,使用set-x
,或bash-x您的脚本
;这将给您在stderr上引用的命令shell——无论如何比echo
有用得多;您无法区分echo“foo bar”
和echo foo bar
,这两个命令之间的差异是巨大而重要的!您还可以使用类似于PS4=':$LINENO+'
的命令和set-x
一起打印每个命令执行时的行号。(另一方面,printf“%q”
是另一个有用的工具,可以放在你的武器库中——使用ksh或bash之类的衍生工具,它对引用的输入进行求值,从而使eval
-安全
foo="this is (foo)"
x="$(sed 's/(/\\\\(/g' <<<"$foo")"
printf '%s\n' "$x"
this is \\(foo)