複数行の正規表現一致後の行の挿入

複数行の正規表現一致後の行の挿入

特定のタグセットに追加する必要があるXMLファイルがあります。デフォルトでは、ファイル構造は次のとおりです。

<key>servers</key>
<dict>
... Server Details ...
</dict>

次の行を一致させたい。

<key>servers</key>
<dict>

次に、サーバー接続を指定するXMLブロックを追加します<dict>。新しいXMLチャンクはかなり長いので、独自のテキストファイルに入れました。

悩んsedawkみましたが、悩みになりました。これを行うためにPerlを使用する例も見ましたが、perlPerlに精通していません。私が知っている限り、sedそれはawkマルチラインマッチングには良くありません。

複数行の一致を実行する理由は、このタグがXMLファイルで頻繁に使用され、内容全体を置き換えるのではなく、そのセクションにブロックを追加する必要があるため<dict>です。<key>servers</key>

答え1

次のことができます。

awk '{print}
     $0 == "<dict>" && previous == "<key>servers</key>" {
       system("cat other-file.xml")
     }
     {previous = $0}'

答え2

sed '/keys_line_1/,/keys_line_last/{/keys_line_last/{
h;s/unique_split_point.*//;r /path/to/insert/file
x;s/.*unique_split_point//;G
}}'

sed仮定を調整する必要がある場合は、完全に許しません。それがするすべてのことは、sed今行ったことの直接的な結果であるため、詳細な部分で非常に小さな間違いが結果を大きく変えることができます。

このように、スクリプトのデバッグは少し狂気と多くの忍耐力なしに失望するsedことができますが、これらの特性を考慮すると、報酬は途方もないかもしれません。私高いlお試しの場合は、この過程でookコマンドを最大限に活用することをお勧めします。

sed ...;l;...complicated_script...;l;...

実は二番目に質問を見るので、最初に考えたよりも簡単なようです。あなたが本当に必要なすべて(私の考えでは)パターン空間を1行ずつ拡張する仕える人一貫した。デフォルトでは、サイクルごとにsed1行だけバッファリングされていますが、コマンドとコマンドはNこのP動作Dを直接制御します。

実は最初は質問を誤解したと思います。行ブロックではなく1行にテキストを挿入したいと思いました。

したがって、次のものが必要な場合があります。

sed '\|<key>servers</key>|,/<dict>/N;P
/\n<dict>/!D;s/.*\n//;r /path/to/file'

これにより、関心のある行を除くすべての行が範囲に含まれます。仕える人あなたの辞書一致はできるだけ早く編集バッファから削除され、r最初のファイルの後にのみターゲットファイルを出力します。辞書*サーバーに従い、一意のポイントであるすべてのシーケンスと一致します。文書出力バッファに追加されたら、次の手順に従ってください。辞書前にewlineがある場合は一致します\n

答え3

こんなのがうまくいくでしょうか?

sed '\|<key>servers</key>|{n
\|<dict>| r other-file.xml
}' file.xml

答え4

Perlタグを追加したので:

perl -pE 'BEGIN{
              $/ = "<key>servers</key>\n<dict>\n"; 
              $content = `cat file.xml`
          }
          $_.=$content' your_input_file

関連情報