我想用来sed
将带有反斜杠的路径转换为带有正斜杠的相同路径:
例如我想通过管道\\path\to\file\
获取/path/to/file
没有任何以下命令有效,我不知道为什么:
第一次尝试:
> echo '\\path\to\file\' | sed 's/\\/\//g'
/path o
ile/
第二次尝试:
echo \\path\to\file\ | sed 's/\\/\//g'
/pathtofile
第三次尝试:
echo "\\path\to\file\" | sed 's/\\/\//g'
dbquote>
如果我尝试通过管道传输,我会得到类似的行为 | tr '\' '/'
我正在寻找正确的答案,如果可能的话,我正在寻找为什么上述尝试都不起作用的解释。不确定这是否重要,但这一切都在zsh 4.2.6 (x86_64-redhat-linux-gnu)
谢谢!
答案1
file='\\path\to\file\'
printf '%s\n' "$file" | tr -s '\\' /
兹什:
setopt extendedglob
print -r -- ${file//\\##/\/}
答案2
不要使用echo
.问题echo
是版本太多,每个版本处理反斜杠的方式略有不同。您的显然是在解释原始字符串中的反斜杠。如果你刚刚这样做了
# first attempt
echo '\\path\to\file\'
我怀疑你会看到
\path o
ile\
同样,在您的所有其他尝试中,问题在于您的使用echo
以及 shell 引用和反斜杠之间的交互echo
,而不是管道的第二部分(sed
或tr
)。
解决方案是使用printf
它 - 它的行为更加一致和可移植,因为它是由 POSIX 指定。
printf '\\\\path\\to\\file\\\n'
得到你
\\path\to\file\
答案3
您可以使用 POSIXheredoc
来执行此操作:
% sed -e 's@\\@/@g' -e 's@\(.\):\(.*\)@/drive/\1\2@' <<'_EOF_'
> c:\some\stupid\windows\place
> _EOF_
/drive/c/some/stupid/windows/place
我的回答有没有办法在函数中获取实际的未解释的 shell 参数更详细地描述了这一点,包括如何read
在必要时通过命令替换将其动态地转换为 shell 变量,并将其作为参数传递给 shell 函数。
在我的回答中在 ssh $host $FOO 和 ssh $host “sudo su user -c $FOO” 类型构造中引用我提出了一种可能不同的、而且我认为更直接的方法来解决本来已经得到很好解答的问题。
编辑:抱歉,我本来忽略了您的要求“解释为什么上面[你的]尝试[引用问题中所示的反斜杠]都不起作用:”
理解答案的技巧虽然本身并不是很神秘,但不幸的是,它相当不直观。我们通常遇到的主要障碍,或者至少我遇到的主要障碍是,它shell
是我们与计算机的默认界面。因此,我认为有时很难记住它只是一个程序;它只是一个程序。它只是一个像其他应用程序一样的应用程序。
如果稍微改变一下事物的名称,可能会更容易看清它;不要称其为“ shell
”,而是尝试将其称为“ command interpreter
”(不过,shell
如果这个词倾向于继承较少的行话内涵并且它的含义可能也很好基本意义比较突出一点)。
我发现,当它变成我的 时,我发现更容易更正确地将更少的控制权shell
归因于我可能会做的事情interpreter
。通过这种方式,我也更容易记住,当它涉及时,它不仅仅解释我,而且,忠于其目的和本质,它试图中间人任何它所了解的对话;如果有机会,它shell
会解释其他应用程序传递的数据,无论是否需要。
我的目的是,command interpreter
默认情况下,它自然地将传递给它的所有信息解释为它自己的语言,但它的语言本身并不一定比任何其他应用程序的语言更正确。当然,对于其他应用程序来说,说好 的语言是有好处的command interpreter
,可以方便地省去他们自己解释你的麻烦,但他们也有同样的权利去尝试,因为它们都只是 中的计算机程序。结尾。
解释命令没有唯一正确或错误的方法,这让其姊妹应用程序的情况变得复杂。就 Unix 而言最接近正确的(因此可以说根本没有)可能是 POSIX 标准,但它肯定为解释留下了一些余地(这说起来很有趣,而且正如我希望的那样,这可能应该说明我的观点)。结果是一种类似于人类模拟语言的许多方言的数字语言(也很有趣)。
(上面的大部分内容只是入门,对于完全理解以下内容可能至少有点不必要,但我希望它会有所帮助。)
当我们将命令传递给它时,shell
它会迭代一系列规则,它被编程为在传递之前以某种顺序考虑解释我们的命令它对我们命令的解释正如它所解释的那样,我们希望它应该如此。我们影响哪些规则以及规则考虑这些规则的顺序的主要手段(当然,除了命令本身)是不同类型的shell quotes
,正如您所发现的,其中通常包括\
反斜杠字符。
其他应用程序有几乎同样多的理由和同样多的权利来应用它们自己的解释规则集,但在第一次执行之前不太可能有机会shell
,因此通常它们的规则将模仿shell
.当他们采用与 相同的引用机制时,这可能会变得复杂shell
,因为这让我们承担了责任(呵呵)到\'"quote our quotes"\'
。当我们的目标应用程序和我们的目标应用程序在引用语法上只有很小的差异时,这种复杂性可能会令人沮丧地放大shell
,并且我们必须通过繁琐的指令间接解决一个问题,以便在翻译过程中不会丢失任何内容。
正如我在上面的代码块中演示的那样,我处理这种情况的首选方法就是直接指示将shell
其粘贴到哪里,可以这么说,并且它应该几乎忽略所有内容,<<'HERE'
因为我认为我可以处理这个问题仅对话,非常感谢,我一定会让它知道\nHERE\n
何时应该再次开始关注。
答案4
在 中bash
,第一次尝试就像魅力一样。这取决于echo
您运行的是什么以及版本。例如,echo
是 bash 内置命令并覆盖/bin/echo
or /usr/bin/echo
。检查man bash
并info zsh
比较他们接受的选项和默认选项。
您真正想要的是强制echo -E
禁用转义序列解释。它是默认的bash
,但显然不是zsh
。您还可以禁用这个特定的内置函数(我没有使用,zsh
所以我不知道如何),或者使用最常见的处理方法:echo
显式调用为/bin/echo
.
编辑:当然你需要单引号,否则 shell 会在echo
有机会之前解释转义序列。