如何用sed插入包含斜杠的字符串? [重复]

问题描述 投票:0回答:11

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

该项目包含诸如

?page=one
之类的 URL。为了使链接在服务器上有效,它必须是
/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
sed
11个回答
340
投票

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

s:?page=one&:pageone:g

您可以使用不属于任一字符串的任何字符作为分隔符。或者,您可以用反斜杠转义它:

s/\//foo/

这会将

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


129
投票

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

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

79
投票

关于 sed 的一个非常有用但鲜为人知的事实是,熟悉的

s/foo/bar/
命令可以使用任何标点符号,而不仅仅是斜杠。 一个常见的替代方案是
s@foo@bar@
,从中可以清楚地看出如何解决您的问题。


13
投票

在特殊字符前添加\:

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


5
投票

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

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

1
投票

replace.txt
应该是

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

1
投票

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

只需使用 |而不是 /


0
投票

匿名者的回答很好。当我尝试转义 HTML 字符串中的引号时,解决了我的问题。

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

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

0
投票

更简单的替代方案是使用 AWK,如此答案

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


-1
投票

您可以使用替代的正则表达式分隔符作为搜索模式,通过反驳它:

sed '\,{path},d'

对于 s 命令:

sed 's,{path},{other_path},'
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.