sed
私はLinuxを使用していますが、これを使用して2つのタグ間のスラッシュ()を削除したいと思います。/
したがって:
<file>/text</file>
<file>/text2</file
<file>/text</file>..
これに関して
<file>text</file>
<file>text2</file
<file>text</file>..
成功事例なしで多くのコードをテストしました。
sed s'/<file>/s|^\.{1,2}/||' fileout
助けてください?
答え1
次の正しい形式のXMLファイルが提供されます。
<?xml version="1.0"?>
<root>
<file>/text</file>
<file>/text2</file>
<file>/text</file>
<file>other text</file>
</root>
file
...値が次から始まる場合は、XMLStarletを使用して各ノード値の最初の文字を削除できます/
。
xmlstarlet edit \
--update '//file[starts-with(text(), "/")]' \
--expr 'substring(text(), 2)' \
myfile.xml
または、より短い構文を使用すると、
xmlstarlet ed \
-u '//file[starts-with(text(), "/")]' \
-x 'substring(text(), 2)' \
myfile.xml
file
次に、入力文書全体で値がで始まるすべてのノードを見つけて、を使用して/
最初の文字を削除しますsubstring()
。
結果:
<?xml version="1.0"?>
<root>
<file>text</file>
<file>text2</file>
<file>text</file>
<file>other text</file>
</root>
これ(そして以下のもの)は、値に改行を含むノードを処理します。
初めてだけでなく、値のどこでも検出したいですか/
?すべてを削除するには、代わりに次のものを使用できcontains()
ますtranslate()
。
xmlstarlet edit \
--update '//file[contains(text(), "/")]' \
--expr 'translate(text(), "/", "")' \
myfile.xml
または単に(translate()
値がない場合、呼び出しは値を変更せずに残します)/
xmlstarlet edit \
--update '//file' \
--expr 'translate(text(), "/", "")' \
myfile.xml
次の入力ファイルが与えられた場合:
<?xml version="1.0"?>
<root>
<file>text/</file>
<file>/text/2</file>
<file>te/x/t/</file>
<file>other text</file>
</root>
...上記のコマンドは、次の結果を生成します。
<?xml version="1.0"?>
<root>
<file>text</file>
<file>text2</file>
<file>text</file>
<file>other text</file>
</root>
答え2
入力(固定構文)XML
ファイル(>
2番目のノードを閉じていないfile
):
<r>
<file>/text</file>
<file>/text2</file>
<file>/text</file>
</r>
現代的な構文と正しいXPath
機能を備えています。fn:replace()
(少しsed
for XPath
、正規表現の使用を許可し、キャプチャグループバージョンXPath
> = 2)、を使用すると、XQuery
次のことができます。
xidel --xquery '
<r>{
for $x in //file
return <file>{replace($x, "^/(.*)", "$1")}</file>
}</r>
' --output-format=xml file.xml
推論:
<?xml version="1.0" encoding="UTF-8"?>
<r>
<file>text</file>
<file>text2</file>
<file>text</file>
</r>
すぐにファイルを編集する必要がある場合は、sponge
次のツールを使用してくださいGNU
more-utils
。
xidel ... file.xml | sponge file.xml
- 正規表現の概要
XPath/XQuery
https://www.regular-expressions.info/xpath.html XPath
はい、サブセットですXQuery
。確認するxpath-xquery-と-xpointerの違いxidel
HTML/XML ジョブのスイス軍用ナイフです。XQuery
プロセッサ(オープンソース)を使用することもできます。BaseX
XQuery
式の実行
答え3
入力に1行に2つのスラッシュしかない場合は、次のawkコマンドを試してください。
$ awk 'BEGIN{OFS=FS="/"}{printf "%s", $1;print$2,$3}' input_file
<file>text</file>
<file>text2</file
<file>text</file>
printfの位置を変更して削除したいスラッシュに基づいて印刷する必要があります。
答え4
使用幸せ(以前のPerl_6)
...Raku(コミュニティサポート)XML
モジュールの使用:
~$ raku -MXML -e 'my $xml = open-xml( $*ARGFILES.Str );
for $xml.elements( :RECURSE(0), :TAG{"file"} ) -> $E {
my $old = $E.contents[0];
my $new = XML::Text.new( text => $old.text.subst(/^ "/" /) );
$E.replace( $old, $new );
}; .say for $xml;' file.xml
Rakuは、高度な機能を備えたPerlファミリのプログラミング言語です。文法テキストを解析するために使用されます。上記では基本バージョンを使用した。XML構文Rakuのオブジェクト指向XML
モジュールであるEngineは、入力XML
ファイルを解析します。したがって、XML要素を認識して繰り返すことができます。
正規表現のみsed
のソリューションの問題の1つXML
は、交換が難しい傾向があることです。交換を特定の深さ/タグに限定するのが難しいことがよくあります。 -moduleを使用するRakuでは、XML
(たとえば、交換を1)に制限できます。最上階と2)。 TAG内でのみ可能です<file>
。これはelements
、制約内で繰り返すようにコードを設定することによって行われます:RECURSE(0), :TAG{"file"}
。ここでは、ノード:NEST
のみを繰り返すように追加することもできます。EVEN
[すべての深さですべてのsを繰り返す場合はTAG
心配しないでください。名前付き引数を設定して:RECURSE(Inf)
削除すると、制限はFalseに設定されます。:TAG
:TAG
これは、各要素の内部部分(つまりTAGではない部分)が実際にオブジェクトであるcontents[0]
変数に割り当てられていることを確認します。問題のスラッシュを削除するために、オブジェクトは何もない文字列として抽出されます。次に、変更されたキーと値のペアを使用して新しい()オブジェクトを作成()します。これから -module のルーチンがこれを行います。$old
XML::Text
$old
.text
subst
"/"
XML::Text.new
$new
text => 'value'
XML
replace
replace( $old, $new )
入力例(@Kusalanandaに感謝!):
<?xml version="1.0"?>
<root>
<file>/text</file>
<file>/text2</file>
<file>/text</file>
<file>other text</file>
</root>
出力例(先行 - /
<file>タグから削除された):
<?xml version="1.0"?><root>
<file>text</file>
<file>text2</file>
<file>text</file>
<file>other text</file>
</root>
https://github.com/raku-community-modules/XML
https://raku.land/?q=XML
https://rakudo.org/
https://raku.org