shell 中反斜杠的处理

shell 中反斜杠的处理

如何echo处理,和其他 shellprintf中的反斜杠?zshbash

在下面我得到以下行为:

$ 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

并得到完全相同的字符串?(在zshbash)?

这是 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 字符。

不要用于echo显示任意字符串,使用printf:

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 中看到的行为。

相关内容