我有一个xml文件,格式如下:
<list>
<version>1.5</version>
<version>1.4</version>
<version>1.3</version>
<version>1.2</version>
</list>
我的想法是我总是用新版本更新第一个版本标签。当我这样做时,我会替换后续的标签。
例如,当我将1.6版本更新为第一个标签(我知道该怎么做)时,以下标签将是:
<list>
<version>1.6</version>
<version>1.5</version>
<version>1.4</version>
<version>1.3</version>
</list>
我试图让两个选项继续下去。
第一个选项: 我首选的选项是搜索xml文件并将版本标签i + 1替换为版本标签i。类似的东西:
sed -E '2,/<version>.*<\/version>/s#<version>(.*)</c>#<version>\1</version>#' file.xml
我在哪里搜索版本的第二个实例并将其替换为第一个版本的实例(目前无效)。
第二个选项: 我的第二个选择是将版本标签存储在变量中:
version=$(grep -oPm1 "(?<=version>)[^<]+" file.xml)
version2=$(grep -oPm2 "(?<=version>)[^<]+" file.xml)
然后用版本1替换版本2并进行替换:
sed -i "s/${version2}/${version}/g" file.xml
然而,这个选项给出了:
sed:-e expression#1,char 9:unterminated's'命令。
当我尝试时:
sed -i "/$version2/s/${version2}/${version}/g" file.xml
我明白了:
未终止的地址正则表达式
显然,任一选项的想法都是将代码放在一个循环中,以便我可以运行它一次。但是,我被困住了,我试过的两个选项都不起作用。
答案 0 :(得分:5)
Don't use text-manipulation tools such as awk
or sed
to work with XML if you can at all avoid it.虽然这个特定的子集可能非常简单,只是为了使方法可行,但掌握正确的工具可以避免以后的麻烦(如果文件格式扩展;如果有人在前面添加评论;等等)。
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
-d '/list/version[last()]'
删除列表中的最后一个version
条目。-i '/list/version[1]' -t elem -n version -v 1.6
在第一个版本当前持有的位置引入了一个名为version
的新元素,其值为1.6
。答案 1 :(得分:0)
使用!或#作为sed中的分隔符而不是/。
它因为匹配和替换变量包含/
而中断