sed インラインでは XML スタイルの入力を変更できません

sed インラインでは XML スタイルの入力を変更できません

問題は、コマンド全体をSEDと同じ行に入れることができないことです。そうしましたが、次のファイルでは機能しません。私の例:

<file>Documents/time/text1</file> //2X slash + 2 words to remove !!
<file>Commun/text2</file>         //1X slash to remove + 1 words to remove
<file>Current/text3</file>        //1X slash to remove + 1 words to remove

このコードがオンラインで機能しないのはなぜですか?

sed 's/Documents//g' | sed 's/time//g' | sed 's/Commun//g' | sed 's/Current//g' | sed 's/Current//g' | sed '/<file>/s|<file>/|<file>|' | sed '/<file>/s|<file>/|<file>|' tracklist.txt > newtracklist.txt

答え1

OPの現在のスクリプトパイプラインを実行すると、入力ファイル()の内容がstdoutとして印刷され、パイプラインが中断されsedますtracklist.txt(つまり、他の出力がないか、コマンドプロンプトに戻りません)。はい推測するOPが言及したときに言及した内容です。it does not work...??

主な問題:入力ファイル()は、最後のスクリプトではなく最初のスクリプトtracklist.txtの引数として提供する必要があります。sedsed

おすすめ:

# instead of this:

sed 's/Documents//g'               | ... |  sed '/<file>/s|<file>/|<file>|' tracklist.txt
                                                                            ^^^^^^^^^^^^^
# do this:

sed 's/Documents//g' tracklist.txt | ... |  sed '/<file>/s|<file>/|<file>|'
                     ^^^^^^^^^^^^^

sedOPパイプラインの更新版を実行すると、次のようになります。

<file>text1</file>
<file>text2</file>
<file>text3</file>

HTML / XMLを解析するためのより良いツールがありますが、OPがそれを使用する必要がある場合は、よりsed効率的な方法で同じ結果を生成することができます。

アイデアにはsedスクリプトが必要です。

sed -E 's|(<file>).*/([^/]+</file>)|\1\2|' tracklist.txt

どこ:

  • -E- 拡張正規表現サポートの有効化
  • (<file>)- (最初のキャプチャグループ)文字列と一致します。<file>
  • ([^/]+</file>)- (2番目のキャプチャグループ)/の後に文字列がないすべての文字と一致します。</file>
  • .*/- 2つのキャプチャグループ間のすべてが/
  • \1\2- 代替文字列は、一緒に追加された2つのキャプチャグループで構成されています。
  • メモ:これは、OPが提供する特定の入力に対して機能します。入力がOPの入力例に示されている形式と異なる形式の場合は、調整が必要になる場合があります。

OPのサンプル入力の場合、以下が生成される。

<file>text1</file>
<file>text2</file>
<file>text3</file>

答え2

入力XMLファイルが与えられると

rルートノードの追加:

<r>
    <file>Documents/time/text1</file>
    <file>Commun/text2</file>
    <file>Current/text3</file> 
</r>

パスワード:

xidel --xquery '
    <r>{
        for $x in //file
        return <file>{tokenize($x, "/")[last()]}</file>
    }</r>
' --output-format=xml --output-node-indent file.xml

生産する:

<?xml version="1.0" encoding="UTF-8"?>
<r>
  <file>text1</file>
  <file>text2</file>
  <file>text3</file>
</r>

説明する:

ここではsed間違ったツールを使用するのではなく、正しいパーサーを使用していますXPathXQuery前者は後者のサブセットです)XML

xidelHTML/XML ジョブのスイス軍用ナイフです。

使用法:

xidel ... file.xml > new_file.xml

編集したい場合飛行中:

xidel ... file.xml | sponge file.xml

sponge~から牛に似た一種の栄養 more-utils

答え3

使用幸せ(以前のPerl_6)

~$ 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.match(/ <?after "/">  <-[/]>+  $/) );
                      $E.replace( $old, $new );
                  };  .say for $xml;'   file.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.path.basename );
                      $E.replace( $old, $new );
                  };  .say for $xml;'   file.xml

Rakuは、高度な機能を備えたPerlファミリのプログラミング言語です。文法テキストを解析するために使用されます。 Raku / Rakudo自体に加えて、コミュニティメンバーはRaku / Rakudoエコシステムのモジュールをサポートしています。これらのモジュールの1つは(楽出身XMLモジュール。

OPの他の質問と同様に、XML-moduleを使用するRakuでは、(たとえば)置換を1に制限できます。最上階と2)。 TAG内でのみ可能です<file>。これはelements、制約内で繰り返すようにコードを設定することによって行われます:RECURSE(0), :TAG{"file"}。参考までに、TAG必要に応じてすべての深さですべてのsを繰り返すことができます。名前付き引数を設定して:RECURSE(Inf)削除すると、制限はFalseに設定されます。:TAG:TAG

上記の最初の答えは、交換に適したタグ/レベルを識別します。これは、各要素の内部部分(つまりTAGではない部分)が実際にオブジェクトであるcontents[0]変数に割り当てられていることを確認します。オブジェクトを文字列として抽出し、目的のオブジェクトを見つけます。次に、変更されたキーと値のペアを使用して新しい()オブジェクトを作成()します。これから -module のルーチンがこれを行います。$oldXML::Text$old.textmatchXML::Text.new$newtext => 'value'XMLreplacereplace( $old, $new )

上記の2番目の答えは、最初の答えを賢く変形させたものです。 OPはパス名を編集しようとしているため、IO::PathRakuオブジェクトクラスに関連するルーチンを使用できます。 Rakuの.IOルーチンはテキストを有効なパス名として理解し、Rakuの.basenameルーチンは最終ファイル名を返します。 Rakuには、さまざまなプラットフォームで正しい(/または\)パス区切り文字を使用するメカニズムがあるため、このアプローチはコードの移植性を向上させる可能性があります。

入力例(@GillesQuénotに感謝!):

<r>
    <file>Documents/time/text1</file>
    <file>Commun/text2</file>
    <file>Current/text3</file>
</r>

出力例:

<?xml version="1.0"?><r>
    <file>text1</file>
    <file>text2</file>
    <file>text3</file>
</r>

https://github.com/raku-community-modules/XML
https://docs.raku.org/type/IO/Path
https://rakudo.org/
https://raku.org

関連情報