如何使用sed插入包含斜杠的字符串?

如何使用sed插入包含斜杠的字符串?,sed,Sed,我有一个VisualStudio项目,是在本地开发的。代码文件必须部署到远程服务器。唯一的问题是它们包含的URL是硬编码的 该项目包含URL,例如?page=one。要使链接在服务器上有效,它必须是/page/one 我已经决定在部署之前用sed替换代码文件中的所有url,但我仍然坚持使用斜杠 我知道这不是一个很好的解决方案,但它很简单,可以节省我很多时间。我必须替换的字符串总数少于10个。必须检查的文件总数约为30个 下面是描述我的情况的示例: 我正在使用的命令: sed -f replace

我有一个VisualStudio项目,是在本地开发的。代码文件必须部署到远程服务器。唯一的问题是它们包含的URL是硬编码的

该项目包含URL,例如
?page=one
。要使链接在服务器上有效,它必须是
/page/one

我已经决定在部署之前用sed替换代码文件中的所有url,但我仍然坚持使用斜杠

我知道这不是一个很好的解决方案,但它很简单,可以节省我很多时间。我必须替换的字符串总数少于10个。必须检查的文件总数约为30个

下面是描述我的情况的示例:

我正在使用的命令:

sed -f replace.txt < a.txt > b.txt
a.txt

?page=one&
?page=two&
?page=three&
运行sed命令后
b.txt
的内容:

pageone
pagetwo
pagethree
我希望
b.txt
包含的内容:

/page/one
/page/two
/page/three

最简单的方法是在搜索/替换行中使用不同的分隔符,例如:

s:?page=one&:pageone:g
您可以使用任何不属于任何字符串的字符作为分隔符。或者,你可以用反斜杠来逃避:

s/\//foo/

它将用
foo
替换
/
。如果您不知道替换字符串中可能出现的字符(例如,如果它们是shell变量),则需要使用转义反斜杠。

s命令可以使用任何字符作为分隔符;使用
s
后面的任何字符。我从小就学会使用
#
。像这样:

s#?page=one&#/page/one#g

在特殊字符之前添加\项:

s/\?page=one&/page\/one\//g

等等。

关于sed,一个非常有用但鲜为人知的事实是,熟悉的
s/foo/bar/
命令可以使用任何标点符号,而不仅仅是斜杠。常见的替代方案是
s@foo@bar@
,从中可以明显看出如何解决您的问题。

这一行应该适用于您的3个示例:

sed -r 's#\?(page)=([^&]*)&#/\1/\2#g' a.txt
  • 我使用
    -r
    来保存一些转义
  • 这条线应该是一、二、三种情况下的通用线。你不必做三次潜艇
使用您的示例(a.txt)进行测试:


replace.txt
应为

s/?page=/\/page\//g
s/&//g

Anonymous的回答很好。\解决了我试图在HTML字符串中转义引号时遇到的问题

因此,如果使用sed返回一些HTML模板(在服务器上),请使用双反斜杠而不是单反斜杠:

var htmlTemplate = "<div style=\\"color:green;\\"></div>";
var htmlTemplate=“”;

在我正在开发的系统中,sed要替换的字符串是用户输入的文本,该文本存储在变量中并传递给sed

如本文前面所述,如果sed命令块中包含的字符串包含sed使用的实际分隔符,那么sed将在出现语法错误时终止。考虑下面的例子:

这项工作:

$ VALUE=12345
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345
这打破了:

$ VALUE=12345/6
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
sed: -e expression #1, char 21: unknown option to `s'
在我的情况下,替换默认分隔符不是一个可靠的解决方案,因为我不想限制用户输入sed使用的特定字符作为分隔符(例如“/”)

但是,转义输入字符串中出现的任何分隔符都可以解决问题。 考虑下面的解决方案,在系统通过SED解析之前,系统地跳过输入字符串中的分隔符字符。 这种转义可以使用sed本身作为替换来实现,即使输入字符串包含分隔符,这种替换也是安全的-这是因为输入字符串不是sed命令块的一部分:

$ VALUE=$(echo ${VALUE} | sed -e "s#/#\\\/#g")
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345/6
我已将其转换为可供各种脚本使用的函数:

escapeForwardSlashes() {

     # Validate parameters
     if [ -z "$1" ]
     then
             echo -e "Error - no parameter specified!"
             return 1
     fi

     # Perform replacement
     echo ${1} | sed -e "s#/#\\\/#g"
     return 0
}
sed
是标准的,因为您可以使用
|
(管道)通过
sed
发送标准流(特别是STDIN和STDOUT),并动态地以编程方式更改它们,使其成为Unix哲学传统中的一个方便工具;但也可以使用下面提到的
-i
参数直接编辑文件。
考虑以下几点

sed-i-e's/now/asd/g'hello.txt
s/
用于用
asd
替换找到的表达式
level

少数人,勇敢者


asd,勇敢的人

/g
代表“全局”,意思是对整条生产线执行此操作。如果您取消了
/g
(使用
s/now/asd/
,则无论如何都需要三个斜杠)并且
now
在同一行上出现两次,只有第一个
now
更改为
asd

少数的男人,少数的女人,勇敢的人


asd男人,少数女人,勇敢者

这在某些情况下很有用,比如在行首更改特殊字符(例如,将一些人用于引用电子邮件线程中先前材料的大于符号替换为水平选项卡,而在行尾保留引用的代数不等式不变),但是,在您的示例中,如果您指定在
很少发生的任何地方都应该替换它,请确保您有
/g

以下两个选项(标志)组合为一个,
-ie

-i
选项用于编辑文件
hello.txt
上的in位置

-e
选项表示要运行的expression/命令,在本例中为
s/


注意:使用
-i-e
搜索/替换非常重要。如果您执行
-ie
,您将为每个文件创建一个附加字母“e”的备份。

一个更简单的替代方法是使用AWK,如下所示:

awk'$0=“prefix”$0”文件>新文件

请参阅本文


仅使用|而不是/

操作系统X上的BSD手册页的可能副本的可能副本说明了s命令:用替换字符串替换模式空间中正则表达式的第一个实例。可以使用反斜杠或换行符以外的任何字符代替斜杠来分隔RE和替换。我会
$ VALUE=$(echo ${VALUE} | sed -e "s#/#\\\/#g")
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345/6
escapeForwardSlashes() {

     # Validate parameters
     if [ -z "$1" ]
     then
             echo -e "Error - no parameter specified!"
             return 1
     fi

     # Perform replacement
     echo ${1} | sed -e "s#/#\\\/#g"
     return 0
}