Sed
如何替換多個文件中的某個模式?
我的目標是更新多個 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>