bash 外壳脚本。我的脚本中的命令替换问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1118601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 21:02:40  来源:igfitidea点击:

Shell scripting. Command substitution issue in my script

linuxbashshellscriptingcygwin

提问by sourcerebels

On both, my Cygwin and my Linux box (Debian) I'm experiencing same issue:

在我的 Cygwin 和 Linux 机器(Debian)上,我都遇到了同样的问题:

I'm working in a shell script with some kind of formatting ids, I want to add a backslash () before a slash occurrence (/).

我正在使用某种格式 ID 的 shell 脚本,我想在出现斜杠 (/) 之前添加一个反斜杠 ()。

My sed script is working well at my terminal:

我的 sed 脚本在我的终端上运行良好:

# export someid="314-12345/08"
# echo "${someid}" | sed 's/\//\\//'

Output:

输出:

314-12345\/08

But not as well if i run command substitution:

但如果我运行命令替换,情况就不一样了:

# someidformatted=`echo "${someid}" | sed 's/\//\\//'`
sed: -e expression #1, char 9: unknown option to `s'

What I'm missing here?

我在这里缺少什么?

Thank you in advance.

先感谢您。

回答by Grzegorz Oledzki

There's no obligation to use / as the separator for sed.

没有义务使用 / 作为 sed 的分隔符。

s/a/c/

May become

可能会变成

s#a#c#

So in your case:

所以在你的情况下:

someidformatted=`echo "${someid}" | sed 's#\/#\\/#'`

would do the job.

会做的工作。

I can only guess that the problem was caused by some lack of / escaping.

我只能猜测问题是由于缺少/转义引起的。

回答by Ville Laurikari

Here's what is going on. From the bash(1) man page, emphasis mine:

这就是正在发生的事情。从 bash(1) 手册页,强调我的:

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by $, ‘, or \.The first backquote not preceded by a backslash terminates the command substitution. When using the $(command) form, all characters between the parentheses make up the command; none are treated specially.
当使用旧式反引号替换形式时,反斜杠保留其字面意义,除非后跟 $、' 或 \。前面没有反斜杠的第一个反引号终止命令替换。使用$(command)形式时,括号之间的所有字符组成命令;没有被特殊对待。

So most likely you need more backslashes for the command substitution than a plain command. You can debug this by setting set -x:

因此,与普通命令相比,命令替换很可能需要更多的反斜杠。您可以通过设置来调试set -x

# someidformatted=`echo "${someid}" | sed 's/\//\\//'`
++ echo 314-12345/08
++ sed 's/\//\//'
sed: 1: "s/\//\//": bad flag in substitute command: '/'
+ someidformatted=
# someidformatted=$(echo "${someid}" | sed 's/\//\\//')
++ echo 314-12345/08
++ sed 's/\//\\//'
+ someidformatted='314-12345\/08'

So, you can see that an occurrence of \\gets turned to \. Adding more backslashes works, but I prefer the $(command)form:

因此,您可以看到出现的\\变成了\。添加更多反斜杠有效,但我更喜欢以下$(command)形式:

# someidformatted=$(echo "${someid}" | sed 's/\//\\//')