用bash替换xml中的标签

Ada*_*dam 0 regex xml linux bash sed

我有一个xml文件,格式如下:

<list>
    <version>1.5</version>
    <version>1.4</version>
    <version>1.3</version>
    <version>1.2</version>
</list>
Run Code Online (Sandbox Code Playgroud)

我的想法是我总是用新版本更新第一个版本标签.当我这样做时,我会替换后续标签.

例如,当我将1.6版本更新为第一个标记(我知道该怎么做)时,以下标记将是:

<list>
    <version>1.6</version>
    <version>1.5</version>
    <version>1.4</version>
    <version>1.3</version>  
</list>
Run Code Online (Sandbox Code Playgroud)

我试图让两个选项继续下去.

第一个选项: 我首选的选项是搜索xml文件并用版本标签i替换版本标签i + 1.就像是:

sed -E '2,/<version>.*<\/version>/s#<version>(.*)</c>#<version>\1</version>#' file.xml
Run Code Online (Sandbox Code Playgroud)

我搜索版本的第二个实例并将其替换为第一个版本的实例(当前不工作).

第二种选择: 我的第二种选择是将版本标签存储在变量中:

version=$(grep -oPm1 "(?<=version>)[^<]+" file.xml)
version2=$(grep -oPm2 "(?<=version>)[^<]+" file.xml)
Run Code Online (Sandbox Code Playgroud)

然后用版本1替换版本2并进行替换:

sed -i "s/${version2}/${version}/g" file.xml
Run Code Online (Sandbox Code Playgroud)

但是,这个选项给出了:

sed:-e expression#1,char 9:unterminated's'命令.

当我尝试:

sed -i "/$version2/s/${version2}/${version}/g" file.xml
Run Code Online (Sandbox Code Playgroud)

我明白了:

未终止的地址正则表达式

显然,任一选项的想法都是将代码放在一个循环中,以便我可以运行它一次.但是,我被困住了,我试过的两个选项都不起作用.

Cha*_*ffy 5

如果完全可以避免使用XML,请不要使用文本操作工具,例如awksed使用XML.虽然这个特定的子集可能非常简单,只是为了使方法可行,但是掌握正确的工具可以避免以后的麻烦(如果文件格式得到扩展;如果有人在前面添加注释等等).

new_version=1.6
xmlstarlet ed \
  -d '/list/version[last()]' \
  -i '/list/version[1]' -t elem -n version -v "$new_version" \
  <old.xml >new.xml
Run Code Online (Sandbox Code Playgroud)
  • -d '/list/version[last()]'删除version列表中的最后一个条目.
  • -i '/list/version[1]' -t elem -n version -v 1.6在第一个版本当前持有的位置引入了一个名为versionvalue 的新元素1.6.

  • xmlstarlet位于EPEL存储库中.有关安装说明,请参阅https://fedoraproject.org/wiki/EPEL. (2认同)