如何echo
处理,和其他 shellprintf
中的反斜杠?zsh
bash
在下面嘚我得到以下行为:
$ echo "foo\bar\baz"
foaaz
$ echo "foo\\bar\\baz"
foaaz
$ echo 'foo\bar\baz'
foaaz
$ echo 'foo\\bar\\baz'
foo\bar\baz
在下面巴什,事情看起来更加一致:
bash$ echo "foo\bar\baz"
foo\bar\baz
bash$ echo 'foo\bar\baz'
foo\bar\baz
bash$
但更具体地说:如何传递包含反斜杠的字符串,例如\\foo\bar\something
到:
echo
printf
print
并得到完全相同的字符串?(在zsh
和bash
)?
这是 zsh 中函数的另一个实验:
function foo
{
echo -E '$1'
}
$ foo \\here\is\some\path
$1
我怎样才能让它打印出来\\here\is\some\path
?
更新(注意:这已经在斯蒂芬的评论中得到了回答)
我在 zsh 5.0.2 中尝试过以下操作:
function foo
{
printf '$s\n' $1
}
foo '\\some\path'
但这打印出来了$s
?
答案1
zsh
echo
以标准方式运行,就像bash
在 UNIX 模式中一样。也就是说,它\b
按照 UNIX 规范的要求扩展为 ASCII BS 字符。
printf '%s\n' "$1"
print -r -- "$1"
也有效,但ksh
/是zsh
特定的。
echo -E - "$1"
zsh
我相信与一些 BSD一起工作。
cat << EOF
$1
EOF
可以在任何类似 Bourne 的 shell 中工作,即使是几十年前没有printf
命令的 shell,但它会产生一个新进程,而且现在确实没有必要,因为我们现在printf
到处都有。
顺便说一句,您需要在 shell 命令行上转义反斜杠,因为它对于 shell 来说是特殊的(除了 之外的每个 shell rc
),因此:
$ foo '\\foo\bar'
foo \\foo\bar
会将"\foo\bar"
字符串传递给foo
无法重新发明丢失的反斜杠的字符串。
答案2
新答案:read -r var
-r raw input - disables interpretion of backslash escapes and line-continuation in the read data
并显示:
printf "%s" "$var"
echo "$var"
应该管用。
所以对于你的 foo 函数:
function foo
{
read -r var
echo -E "var is : ${var}"
}
$ foo
\\here\is\some\path
var is : \\here\is\some\path
下面的旧答案(没有回答,但也许有用^^)
只需将每个替换\
为\\
告诉 shell“它是\
我想要的”。否则(例如在 zsh 中,在您的示例中)很可能意味着\b
“1 退格”,或其他什么。
例如,您可以使用 sed:
sed -e 's,\\,\\\\,g' < the_original > the_escaped_backslaches_version
(看看你如何还需要在那里转义“\”,告诉 sed 同样的事情:“它是我想要的字面上的“\”)(注意我用 ' ' 而不是 " " 包围它,以避免 shell 解释大部分也是)
答案3
一般来说你不能,因为反斜杠是转义字符(因此当需要其字面值时必须转义)。 BASH 为此目的提供了单引号,但是您不能在单引号字符串中使用转义单引号。
至于echo
差异,它是内置的,并且跨 shell 的行为可能有所不同(在某种程度上)。例如,BASH 内置有一个-e
选项告诉它解释反斜杠序列 - 使用它您将获得在 Z shell 中看到的行为。