S
文字を次に置き換える必要がありますT
。
<episode-num system="onscreen">S1 E12</episode-num>
私の予想結果:
<episode-num system="onscreen">T1 E12</episode-num>
Gitがどのように深く機能するのかわかりませんが、XMLタグの対応する文字を変更するために使用し、フォーラムで調査した結果、いくつかの情報を見つけて次のコマンドラインを試しました。
sed -e :l -e 's@\(<episode-num system="onscreen">.*\)S\([^amp;]\)\(.*</episode-num>\)@\1T\2\3@;tl' guide.xml
しかし、うまくいきません。助けてください。
答え1
次のXML文書があるとしましょう。
<data>
<episode-num system="onscreen">S1 E12</episode-num>
<episode-num system="onscreen">S1 S12</episode-num>
<episode-num system="onscreen">T1 S12</episode-num>
</data>
S
...ノード値のすべての文字を置き換えようとしています。T
episode-num
から始まるS
。
xmlstarlet
次のことができます。
xmlstarlet ed -u '//episode-num[starts-with(text(),"S")]' \
-x 'translate(text(),"S","T")' file.xml
episode-num
文書内の場所に関係なく、すべてのノードを変更できます。ただ修正したい場合特別なノードをクリックし、//episode-num
XPath式をより正確なパスに変更します。
上記のサンプル文書では、上記のxmlstarlet
コマンドは次のように生成します。
<?xml version="1.0"?>
<data>
<episode-num system="onscreen">T1 E12</episode-num>
<episode-num system="onscreen">T1 T12</episode-num>
<episode-num system="onscreen">T1 S12</episode-num>
</data>
とxq
(からhttps://kislyuk.github.io/yq/)のようなxmlstarlet
上記と:
xq -x '(.data."episode-num"[] | select (."#text"|startswith("S")))."#text" |= gsub("S";"T")' file.xml
これは、入力文書がサンプル文書と同じ構造を有すると仮定する。 XMLパーサーを使用して文書を解析し、内部的にJSONに変換します。生成されたJSONドキュメントを呼び出してjq
与えられた式を適用し、最後にすべてをXMLに変換します。
私が使用しているサンプル文書の場合、式が実際に適用される内部JSON文書はjq
次のとおりです。
{
"data": {
"episode-num": [
{
"@system": "onscreen",
"#text": "S1 E12"
},
{
"@system": "onscreen",
"#text": "S1 S12"
},
{
"@system": "onscreen",
"#text": "T1 S12"
}
]
}
}
答え2
行に別の文字列が含まれている場合にのみ、特定の文字列を置き換えます。sed
文字列を含む行だけを置き換えます。free
sed '/free/s/i/I/g' example.txt
'/free/s/i/I/g'
/free/
- この文字列が含まれている場合にのみ行を置き換えます。s
- sedの代替コマンド/i/
- 一致させる正規表現は何ですか?/I/
- 一致する部分文字列を置き換える/g
- ラインのすべての試合に対して交換を繰り返す交換フラグ
仮説に対する解決策
あなたのテスト文字列は<episode-num system="onscreen">
次の内容を含むファイルがあるとします。
$ cat test.xml
<data>
<episode-num system="onscreen">S1 E11</episode-num>
<episode-num system="onscreen">S1 E12</episode-num>
<episode-num system="onscreen">T1 E13</episode-num>
<some data>S1 E1</episode-num>
</data>
あなたのsedソリューションは次のとおりです
$ sed '/<episode-num system="onscreen">/s/S/T/g' test.xml
<data>
<episode-num system="onscreen">T1 E11</episode-num>
<episode-num system="onscreen">T1 E12</episode-num>
<episode-num system="onscreen">T1 E13</episode-num>
<some data>S1 E1</episode-num>
</data>
このソリューションのソースはここ。
答え3
Perl one-lignerは良いアプローチではありません。それでも:
perl -MXML::DT -e 'print dt("ex1.xml", "episode-num" => sub{$c=~ s/S/T/; toxml})'
どこ:
-XML::DT
= XML :: DTモジュールをインポートして使用します(この場合はdt
関数dt( file, processor)
=提供されたプロセッサを使用してファイルを下に翻訳するepisode-num => sub{...}
=sub
すべての要素に適用episode-sum
$c = s/S/T/ ; toxml
=要素コンテンツのSをT(= $ c)に置き換えて、episode
XML要素を再計算します。
(必要ならsudo cpanm XML::DT
)