Sed:テキストファイルで次の行\ n記号を置き換える方法は?

Sed:テキストファイルで次の行\ n記号を置き換える方法は?

エラーを修正し、次の構造のXMLファイルで2番目のタグを2番目のタグ</time>に置き換える必要があります。</tags>

<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>

各項目には2つの閉じるタグがあるので、sedを使用してこれを実行しようとしています。</time>アイデアは</time><geo>に置き換えることです</tags><geo>

ところで途中に次の行記号があって使っているのに動作しませんね\n

sed 's/time>\n<geo>/tags>\n<geo>/g' old.xml > new.xml

答え1

Sed は入力を 1 行ずつ処理するため、入力に改行文字が自発的に表示されません。あなたができることは;で終わる行を一時停止し、</time次の行で始まる前の行<geo>を置き換えることです。 (これはsedで「スペース予約」を使用して可能ですが、スペースを保存する必要がある場合はawkまたはperlに切り替えることをお勧めします。)

ただし、例の入力に応じてで始まる行に</time>変更できます。</tags><tags>

sed -e '/^<tags>/ s!</time>$!</tags>!'

答え2

問題を簡単に解決する他の方法があるかもしれませんが、質問に対する答えは簡単です。sedデフォルトでは、1つの行は2つのバッファで一度に処理されます。 1つは行周期にわたって持続するh古い空間と呼ばれ、もう1つはサイクルごとに少なくとも1回フラッシュされるパターン空間と呼ばれます。後者はすべての編集が行われる場所です。 。

Lookahead 機能は、2 つの方法のいずれかで取得できます。言い換えれば、バッファを交換して比較する命令をより良く使用するために、古いラインを保存し、ラインサイクルよりも遅くすることができる。これには、[hH]old、[gG]et、ex変更(それぞれ保存、コピー、および交換)などのコマンドの基本要素が含まれます。小文字の形式は上書きされ、大文字の形式はターゲットバッファに追加されます。

あるいは、各サイクルで読み取られた数の入力ラインを常に削除する継続的な編集アルゴリズムに将来のラインを配置することもできます。ここでは後者を好む。特にコマンドをsed使用すると、非常にシンプルで効率的ですN;P;D

サンプルデータを使用したデモは次のとおりです。

sed '$!N;s/ime\(>\n<geo\)/ags\1/;P;D
'  <<\IN
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
IN

Next、Print、およびDelete は、小文字と同様に、n;p;dそれぞれ次の入力行を取得して印刷し、パターン空間から削除します。小文字と異なるN(状況が少し異なる場合)、これら3つはパターン空間全体ではなく改行境界で動作します。

  • N次の入力行は、パターンスペースのewline文字の後に追加されます\n
  • P\nパターン空間で最初に表示されるewline文字のみが印刷されます。
  • D\n現在のループのスクリプトを終了する前に、パターンスペースに最初に表示されるewlineのみが削除され、パターンスペースの残りの内容とともにキューに追加されます。または、削除操作の後に何もない場合は、次の行を通常どおりキューに入れます。

sedこれら3つが連携して、ファイルの編集ウィンドウを非常にシンプルで効率的に拡張できます。sedファイルをスライドさせ、各サイクルは、スクリプト作成者の指示に従って引き続き削除し、補足する一連の行から最も古い行だけを印刷しますsed。ラインサイクル。

そして、次の行のプレビューは簡単に拡張可能です。スクリプト全体に4行のパターンスペースウィンドウが含まれるようにするには、次のようにします。

sed -e '1{N;N' -e '};N;...;P;D'

...または多分もっと役に立つかもしれません...

sed -e ':next
    $!{/\(.*\n\)\{3\}/!{
        N;b next' -e '}
    };...cmds...;P;D'

...sed入力ラインだけが描画され、他のコマンドが実行される前に十分になるまで続けます。パターンスペースにewline文字が3つ未満で、\n現在の行が最後の行ではない場合。これは、後続のコマンドの編集内容に関係なく発生します。

答え3

この質問に文学的に答えてください。

私はちょっとしたチートを使ってこの問題を解決しました(編集するテキストが複数行にわたっています)。

cat input.txt | tr '\n' '@' | sed -e 's/txt@iam@interestedin/iaminterested@intxt/g' | tr '@' '\n' > output.txt

確認する唯一のことは、改行文字を置き換える文字が入力にすでに存在しないことです。

関連情報