bash 多行 sed 表达式不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22040979/
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-18 09:42:41  来源:igfitidea点击:

multi-line sed expression doesnt work

linuxbashshellsed

提问by anubhava

I'm trying to insert specific xml configuration inside a specific xml element in a configuration file with sed in a bash shell script. When using the sed command on one line it works but when the expression is on multiple lines, it doesnt.

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

I'm trying to insert the xml configuration inside the element which is almost in the middle of the file so i was using the line to test sed 's//\nconfig/gi' file.xml and that works, but i need to add a lot more configuration, so the resulting sed command is like this:

我试图在几乎位于文件中间的元素中插入 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

I originally wrote this as a here document in bash, but it turns out that the sed command itself needs escaping/line continuation character anyway so it didnt help much with having a prettier code.

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

The command above gives me the error message "unterminated address regex" and i cant really see the reason why since its basically sed 's/pattern/replace/' which is the syntax. If im adding the s/ to the start of the sed command i just get a message saying that the s was not terminated properly.

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

I have been searching for quite some time to try to figure how to manage multiple line seds script and i though i was just going to write a sed script but then i need another script as well in addition to the shell script and im not sure i would want that just for a configuration change, it seems a little overkill.

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

回答by anubhava

You should better store your XML snippet in a temp file and then use this simple sed with rcommand:

您应该更好地将您的 XML 片段存储在一个临时文件中,然后使用这个简单的 sedr命令:

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

Where _tempis this:

_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>

回答by mockinterface

As was mentioned in the comments the forward slash as the delimiter is taking the hard road. Generally, however, you need to prefix with s(you say so in the question, but then omit it in the regex), otherwise sed will think bis a branching command, and you'll get the address error. Also you need to prefix every <and /with backslashes, and it's also good to escape the quotes.

正如评论中提到的,正斜杠作为分隔符走的是艰难的道路。但是,通常您需要以前缀s(您在问题中这么说,但在正则表达式中省略它),否则 sed 会认为b是一个分支命令,并且您将收到地址错误。此外,您需要在 each<和 and/前面加上反斜杠,并且转义引号也很好。

Here's your regex working,

这是你的正则表达式工作,

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

现场观看