【问题标题】:multi-line sed expression doesnt work多行 sed 表达式不起作用
【发布时间】:2014-02-26 20:28:20
【问题描述】:

我正在尝试使用 bash shell 脚本中的 sed 在配置文件中的特定 xml 元素中插入特定的 xml 配置。在一行上使用 sed 命令时,它可以工作,但当表达式在多行上时,它就不行了。

我正在尝试将 xml 配置插入到几乎位于文件中间的元素中,因此我使用该行来测试 sed 's//\nconfig/gi' file.xml 并且有效,但是我需要添加更多配置,所以生成的 sed 命令是这样的:

sed -i '
/broker/broker\n \
    <plugins> \
        <jaasAuthenticationPlugin configuration="activemq" /> \
        <authorizationPlugin> \
            <map> \
                <authorizationMap> \
                    <authorizationEntries> \
                        <authorizationEntry topic=> read="admins" write="admins" admin="admins" /> \
                        <authorizationEntry queue=> read="admins" write="admins" admin="admins" /> \
                    </authorizationEntries> \
                </authorizationMap> \
            </map> \
        </authorizationPlugin>
    </plugins>/' $ACTIVEMQ_CONFIG

我最初在 bash 中将其写为 here 文档,但事实证明 sed 命令本身无论如何都需要转义/行继续符,因此它对拥有更漂亮的代码没有多大帮助。

上面的命令给了我错误消息“未终止的地址正则表达式”,我真的看不出原因,因为它基本上是 sed 's/pattern/replace/' 这是语法。如果我将 s/ 添加到 sed 命令的开头,我只会收到一条消息,指出 s 没有正确终止。

我一直在寻找相当长的时间来试图弄清楚如何管理多行 seds 脚本,虽然我只是要编写一个 sed 脚本,但是除了 shell 脚本和 im 之外,我还需要另一个脚本不确定我是否只是为了更改配置而需要它,这似乎有点矫枉过正。

【问题讨论】:

  • &lt;/authorizationPlugin&gt; 需要\
  • 您使用正斜杠作为 sed 分隔符,但替换文本中也有正斜杠。如果您将 sed 斜杠替换为其他内容 - 例如 sed -i 's#broker#broker\n etc#' 怎么办?

标签: linux bash shell sed


【解决方案1】:

您最好将您的 XML sn-p 存储在一个临时文件中,然后将这个简单的 sed 与 r 命令一起使用:

sed -i.bak '/broker/r _temp' file.xml

_temp 在哪里:

cat _temp
<plugins>
    <jaasAuthenticationPlugin configuration="activemq" />
    <authorizationPlugin>
        <map>
            <authorizationMap>
                <authorizationEntries>
                  <authorizationEntry topic=> read="admins" write="admins" admin="admins" />
                  <authorizationEntry queue=> read="admins" write="admins" admin="admins" />
                </authorizationEntries>
            </authorizationMap>
        </map>
    </authorizationPlugin>
</plugins>

【讨论】:

  • 这似乎更干净了,谢谢你告诉我这件事,下次我会检查 r 命令,但现在我认为我只需要转义或只是另一个分隔符
  • 当然是你的电话。如果我这样做,那么我会保持我的脚本易于阅读,并且可以为将来的更改进行维护。
  • 不如你说的那样做,脚本会像你说的那样更容易阅读。我想我只是用配置创建一个子目录。也喜欢带有 .bak 参数的 -i 。当时似乎有点不必要,但是当不得不对多个配置执行此操作时,它确实会清理一下,并且也可以更轻松地编辑 xml。
  • 很高兴你喜欢它。
【解决方案2】:

正如在 cmets 中提到的,正斜杠作为分隔符正在走艰难的道路。但是,一般情况下,您需要以s 为前缀(您在问题中这么说,但随后在正则表达式中将其省略),否则 sed 会认为b 是一个分支命令,您会得到地址错误。此外,您还需要在每个 &lt;/ 前加上反斜杠,并且最好将引号转义。

这是你的正则表达式,

sed -i 's/broker/broker\n \
<plugins> \
    <jaasAuthenticationPlugin configuration=\"activemq\" \/> \
    <authorizationPlugin> \
        <map> \
            <authorizationMap> \
                <authorizationEntries> \
                    <authorizationEntry topic=> read="admins" write="admins" admin="admins" \/> \
                    <authorizationEntry queue=> read="admins" write="admins" admin="admins" \/> \
                <\/authorizationEntries> \
            <\/authorizationMap> \
        <\/map> \
    <\/authorizationPlugin> \
<\/plugins>/'

See it live

【讨论】:

  • 你们很快 :) 完全错过了我在 xml 中使用相同的字符,感谢您这么快指出这一点
  • 当然,我就是不知道是哪一个
猜你喜欢
  • 2015-12-18
  • 2012-12-18
  • 2014-09-03
  • 1970-01-01
  • 2013-02-27
  • 2016-08-16
  • 1970-01-01
  • 2015-06-19
  • 1970-01-01
相关资源
最近更新 更多