SED コマンドは、2 つのタグ間のスラッシュ「/」を削除します。

SED コマンドは、2 つのタグ間のスラッシュ「/」を削除します。

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()(少しsedfor 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

答え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 のルーチンがこれを行います。$oldXML::Text$old.textsubst"/"XML::Text.new$newtext => 'value'XMLreplacereplace( $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

関連情報