如何用sed替换包含斜杠的字符串?

时间:2013-05-28 11:21:39

标签: sed

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

项目包含?page = one 等网址。要使链接在服务器上有效,必须为 / page / one

我决定在部署之前用sed替换我的代码文件中的所有URL,但是我坚持使用斜杠。

我知道这不是一个漂亮的解决方案,但它很简单会省去很多时间。我必须替换的字符串总数小于10.必须检查的文件总数是~30。

描述我的情况的示例如下:

我正在使用的命令:

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

replace.txt,其中包含所有字符串:

s/?page=one&/pageone/g
s/?page=two&/pagetwo/g
s/?page=three&/pagethree/g

A.TXT:

?page=one&
?page=two&
?page=three&

运行sed命令后b.txt的内容:

pageone
pagetwo
pagethree

我想要b.txt包含:

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

11 个答案:

答案 0 :(得分:239)

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

s:?page=one&:pageone:g

您可以将任何字符用作不属于任一字符串的分隔符。或者,你可以用反斜杠来逃避它。

答案 1 :(得分:88)

s命令可以使用任何字符作为分隔符;使用s后出现的任何角色。我被提起来使用#。像这样:

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

答案 2 :(得分:53)

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

答案 3 :(得分:5)

在特殊字符之前添加\:

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

答案 4 :(得分:4)

在我正在开发的系统中,要由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
}

答案 5 :(得分:3)

此行适用于您的3个示例:

sed -r 's#\?(page)=([^&]*)&#/\1/\2#g' a.txt
  • 我使用-r来保存一些转义。
  • 这条线对于你的一,二三个案例应该是通用的。你没必要做3次

使用您的示例(a.txt)进行测试:

kent$  echo "?page=one&
?page=two&
?page=three&"|sed -r 's#\?(page)=([^&]*)&#/\1/\2#g'
/page/one
/page/two
/page/three

答案 6 :(得分:2)

sedstream editor,因为您可以使用|(管道)发送标准流(具体是STDIN和STDOUT)到{{1并以编程方式动态更改它们,使其成为Unix哲学传统中的一个方便工具;但也可以使用下面提到的sed参数直接编辑文件 请考虑以下

-i

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

  

少数人,勇敢者。

           

勇敢的asd。

asd代表&#34; global&#34;,意思是为整行执行此操作。如果您不使用/g(使用/g,则无论如何都需要三个斜杠)并且s/few/asd/在同一行显示两次,只有第一个few已更改为few

  

少数男性,少数女性,勇敢者。

           

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

这在某些情况下非常有用,例如在行的开头更改特殊字符(例如,替换某些人用来引用带有水平制表符的电子邮件主题中的先前材料的大于号符号,同时在以后留下引用的代数不等式在未经修改的行中),但是在您指定任何地方 asd的示例中,应该替换它,确保您拥有few

以下两个选项(标志)合并为一个/g

-ie选项用于修改文件-i上的 i n位置。

hello.txt选项表示要运行的 e xpression /命令,在本例中为-e

注意:使用s/进行搜索/替换非常重要。如果您执行-i -e,则可以使用字母&#39; e&#39;创建每个文件的备份。追加。

答案 7 :(得分:1)

replace.txt应该是

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

答案 8 :(得分:1)

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

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

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

答案 9 :(得分:0)

一个更简单的选择是使用this answer上的AWK:

awk '$0="prefix"$0' file > new_file

答案 10 :(得分:0)

请参阅这篇文章 http://netjunky.net/sed-replace-path-with-slash-separators/

只需使用|代替/