我的目标是更新多个 XML 文件中的版本号,如下所示
<?xml version="1.0" encoding="UTF-8"?>
<Component xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
enter code here
xml 文件中的版本可能不同,
<?xml version="1.0" encoding="UTF-8"?>
<Component xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>27.0</apiVersion>
enter code here
我尝试了几个这样的选项
find force-app -type f -name "*-meta.xml" -exec sed -i '' -e 's/\(<apiVersion>\)\([0-9]+\.0\)\(<\/apiVersion>\)/<apiVersion>52.0<\/apiVersion>/' {} \;
和这个
find force-app -type f -name "*-meta.xml" -exec sed -i '' -e '/<apiVersion>/s/\(\d\+\)/52.0/' {} \;
但他们没有工作
答案1
与往常一样,您确实不想使用面向行的文本编辑工具修改 XML 文件。 XML 不是换行符分隔的文档格式。
要更新/Component/apiVersion
单个 XML 文档中的节点值,请考虑使用xmlstarlet
如下所示:
xmlstarlet ed \
-N x='http://soap.sforce.com/2006/04/metadata' \
-u '/x:Component/x:apiVersion' -v '52.0' file-meta.xml
XPath 表达式/x:Component/x:apiVersion
将匹配您想要在名为的命名空间中更新的节点x
(这是为了-N
匹配文档中的命名空间而定义的)。通常,即当 XML 文档没有名称空间时,您不必像我们在这里所做的那样-N
为节点名称添加前缀。x:
新值由 给出-v
。
您可以就地编辑多个文件,如下所示:
xmlstarlet ed --inplace \
-N x='http://soap.sforce.com/2006/04/metadata' \
-u '/x:Component/x:apiVersion' -v '52.0' *-meta.xml
或者,从以下位置调用它find
:
find force-app -type f -name '*-meta.xml' \
-exec xmlstarlet ed --inplace \
-N x='http://soap.sforce.com/2006/04/metadata' \
-u '/x:Component/x:apiVersion' -v '52.0' {} +
如果您只想在值尚未存在时进行更改52.0
,请改用 XPath 表达式/x:Component/x:apiVersion[text() != "52.0"]
。
使用xq
(XML 解析器,一部分yq
,YAML 包装器jq
,JSON 解析器,来自https://kislyuk.github.io/yq/):
$ xq -x '.Component.apiVersion |= "52.0"' file.xml
<Component xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>52.0</apiVersion>
</Component>
答案2
如果您的文件都像您显示的那样简单,您可以执行以下操作:
find force-app -type f -name "*-meta.xml" \
-exec sed -i '' -e 's|<apiVersion>[0-9]*[0-9.]*[0-9]*</apiVersion>|<apiVersion>52.0</apiVersion>|' {} \;
请注意,在 Linux 上,这会出现错误,您可以使用以下命令代替:
find force-app -type f -name "*-meta.xml" \
-exec sed -i 's|<apiVersion>[0-9]*[0-9.]*[0-9]*</apiVersion>|<apiVersion>52.0</apiVersion>|' {} \;