Sed

如何替換多個文件中的某個模式?

  • April 27, 2021

我的目標是更新多個 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/' {} \;

但他們沒有工作

如果您的文件都像您展示的那樣簡單,您可以這樣做:

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>|' {} \;

像往常一樣,您真的不想使用面向行的文本編輯工具來修改 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"]


使用(來自https://kislyuk.github.io/yq/xq的一個 XML 解析器,yq一個 YAML 包裝器jq,JSON 解析器的一部分):

$ xq -x '.Component.apiVersion |= "52.0"' file.xml
<Component xmlns="http://soap.sforce.com/2006/04/metadata">
 <apiVersion>52.0</apiVersion>
</Component>

引用自:https://unix.stackexchange.com/questions/645406