gawkで混合改行形式を維持する方法は?

gawkで混合改行形式を維持する方法は?

Unix(LF)およびWindows(CR / LF)スタイルの改行文字を含む入力ファイルがあります。 (特にLinuxシステムのXMLですが、いくつかの生のHTTPヘッダーが含まれており、HTTPはヘッダーとしてCRLFを好みます。)

    <response_page cause="default">
      <response_type>custom</response_type>
      <response_header>HTTP/1.1 200 OK^M
Cache-Control: no-cache^M
Pragma: no-cache^M
Connection: close</response_header>

私はこのファイルを繰り返すgawkスクリプトを書いてXML *にいくつかの簡単な修正を加えています。唯一の問題は、LFとCRLFの有効なRSを読みますが、それに関係なくLFのみを出力することです...本質、CRが削除されます。

私はさまざまなアプローチを試しましたが、その中で最も野心的なものは、RSの正規表現マッチングとRT印刷です。

BEGIN { RS = "\r\n|\n"; go = "no" }
(go ~ /yes/) { 
    sub(/false/, "true", $0)
    go = "no"
}
($0 ~ /<signature signature_id="200000017">/) { 
    print "Found signature!"
    go = "yes"
} 
{ 
    printf $0 RT
}

ミックスプラットフォームRSターミネーターを再現するための愚かな態度を取るためのアドバイスに感謝します。

*この場合の簡単な調整は、正しい署名IDを持つ行の次の行で「false」を「true」に変更することです。私はXMLパーサーを使用することがこれを行う正しい方法であることを十分に知っていますが、これらの軽量要件のためにXML解析の苦痛と不安を避けようとしています。

修正する:

このソリューションは、Linuxで実行されているときに機能することがわかりました。 WindowsでCygwin gawkで実行すると、CRLF / LFの区切りが明らかにミュートされ、期待どおりに機能しません。私はPeter.Oに答えのポイントを与えます。彼は私が試したことを本質的に再び言いましたが、彼は徹底的なやり方でしたので、私たちが同じことをしていて私がうまくいかないことに気づいたので、私は私の家に疑問を抱きます。

ベストアンサー1

組み込み変数を使用できますRT

RT はレコードを読み込むたびに設定されます。 RS(Record Separator)で表されるテキストと一致する入力テキストが含まれています。この変数は gawk 拡張です。

printf '%s\n' LF CRLF$'\r' | 
  gawk 'BEGIN { RS = "\r\n|\n" }
       { printf($0 RT) }'

パイプ接続時の出力sed -n l- 表示CR〜のように\rend-of-line〜のように$- どちらにsed次の文字があることを示します。\n(またはend-of-input

LF$
CRLF\r$

ただし、ターミネータをCRLFからLFに、またはその逆に切り替えたい場合は、次の2つのことがあります。

printf '%s\n' was-LF was-CRLF$'\r' | 
  gawk 'BEGIN { RS = "\r\n|\n" }
        RT == "\r\n" { printf($0 "\n") }
        RT == "\n"   { printf($0 "\r\n") }'

パイプ接続時の出力sed -n l

was-LF\r$
was-CRLF$

if注:テストが(デフォルト)コードの最初の行ではない場合は、それを使用する必要があります。

  gawk 'BEGIN { RS = "\r\n|\n" }
        { # some processing code here (before the tests)
          if( RT == "\r\n" ) { printf($0 "\n") }
          if( RT == "\n")    { printf($0 "\r\n") } }'

おすすめ記事