如何使用bash解析下面的xml元素定义elment

如何使用bash解析下面的xml元素定义elment,xml,bash,parsing,Xml,Bash,Parsing,我有这个给定的xml,我只需要更改其中的1个元素,它将始终位于 标题字符串(这是需要更改的),目前我使用sed更改它 sudo sed -i -E 's/_THIS_IS_NEED_TO_CHANGE_/_NEW_STR_/g' the_file.xml" 但这是错误的,因为“this_is_NEED_TO_CHANGE”可以更改为另一个字符串 <plist version="1.0"> <dict>

我有这个给定的xml,我只需要更改其中的1个元素,它将始终位于 标题字符串(这是需要更改的),目前我使用sed更改它

sudo sed -i -E 's/_THIS_IS_NEED_TO_CHANGE_/_NEW_STR_/g' the_file.xml"
但这是错误的,因为“this_is_NEED_TO_CHANGE”可以更改为另一个字符串

<plist version="1.0">
        <dict>
                <key>items</key>
                <array>
                        <dict>
                                <key>metadata</key>
                                <dict>
                                        <key>bundle-identifier</key>
                                        <string>xxxx</string>
                                        <key>bundle-version</key>
                                        <string>xxxx</string>
                                        <key>kind</key>
                                        <string>software</string>
                                        <key>platform-identifier</key>
                                        <string>xxxxx</string>
                                        <key>title</key>
                                        <string>_THIS_IS_NEED_TO_CHANGE_</string>
                                </dict>
                        </dict>
                </array>
        </dict>
        </plist>

项目
元数据
包标识符
xxxx
捆绑版本
xxxx
友善的
软件
平台标识符
xxxxx
标题
_这是你需要改变的_
**更新***
我无法安装任何其他Linux应用程序

我需要使用默认安装的Linux工具执行此操作,如果没有任何其他工具,您可以使用awk将输出重定向到tmp文件,然后将该tmp文件移回原始文件。因此,将文件plist与示例中的源数据一起使用:

awk -v yourtext="_NEW_STR3_" -F [\<\>] '/<key>/ { field=$3;print $0 } /<string>/ { if (field=="title") { match($0,$3);printf "%s%s%s\n",substr($0,1,RSTART-1),yourtext,substr($0,RSTART+RLENGTH,length($0)) } } !/<string>/&&!/key>/ {print $0}' plist > plist.tmp && mv -f plist.tmp plist
awk-v yourtext=“\u NEW\u STR3”\uf[\]'/{field=$3;print$0}/{if(field==“title”){match($0,$3);printf“%s%s%s\n”、substr($0,1,RSTART-1)、yourtext($0,RSTART+RLENGTH,length($0))}/&/key>/{print$0}'plist>plist.tmp&&mv-f plist.tmp plist
这将字段分隔符设置为<或>,并将要打印的新内容作为变量yourtext传递。然后,它检查带有的行并获取内容,将它们放在变量字段中。对于包含的行,如果字段变量先前已设置为title,则将行打印到字符串内容,打印新内容(包含在变量“yourtext”中),然后打印行的其余部分。在所有其他情况下,只需按原样打印该行即可

或者,您可以使用sed:

sed -Ei '/<key>title<\/key>/ {n;s/(^.*<string>)(.*)(<\/string>$)/\1_NEW_STR_4\3/g}' plist
sed-Ei'/title/{n;s/(^.*)(.*)($)/\1\u NEW\u STR\u 4\3/g}plist

搜索行标题,然后移动到下一行,并将该行拆分为括号中指定的三个部分。打印第一部分,然后打印修改后的文本,然后打印最后的第三部分

我建议使用XML/HTML解析器(xmlstarlet,xmllint…),但不能。这就是我所拥有并需要解决的…标题是否总是相同的?是的,可以是:title@user63898:文件前面是否有另一个标题,并且是否确定要更改的字符串将单独在一行中?毕竟,将字符串部分与对应的键放在同一行是有效的XML。