複数のファイルの特定のパターンを置き換える方法は?

複数のファイルの特定のパターンを置き換える方法は?

私の目標は、以下のように複数の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で更新するノードと一致します。通常、つまり、XML文書に名前空間がない場合は、ここで行ったようにノード名の前に接頭辞を付ける必要はありません。新しい値はで与えられます。x-N-Nx:-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パーサー、fromhttps://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>

おすすめ記事