木っ端拾いの材木流し

Cannot see the wood for the trees.

特定の文字列を含むセクションだけを抜き出す

見出し("*"で始まる行)+それに続く複数行の本文+日付区切り"====="で構成されたテキストから特定の文字列を含むセクションを抜き出す。

gawk 'BEGIN {q="検索したい文字列"; IGNORECASE=1; ORS="\r\n"} $0 ~ ("^*[^*]+" q) {o=1} (/^*[^*]/ && $0 !~ q) || /^=====/ {o=0} o {print}' 入力ファイル

cygwingawkで改行コードがCR+LFのファイルを処理する場合、ORS="\r\n"で出力レコードセパレータを指定する。(無指定だとLFになる)
cygwingawkは入力行区切りの扱いがちょっと変で、RSが無指定の場合は改行コードがCR+LFでもLFでも行区切りとして認識する。デフォルトのRSが"\r\n|\n"なのかと思ったが、RS="\r\n"とするとどちらの改行コードも認識せず、RS="\n"だとどちらも認識する。cygwinがbinmodeでもtextmodeでも現象は同じだった。gawkの内部で最初にCR+LFをLFに変換してから処理しているように見える。

追記

現象がつかめませんが、gawk の Texinfo ファイルを読む限り Cygwin だから特別とかいうこともなさそうです。

Cygwin の gawk - 日本 GNU AWK ユーザー会 0.2

たとえば、

1行目[CR][LF]
2行目[CR][LF]

という内容のinfileがあって

gawk 'BEGIN{RS=文字列1;ORS=文字列2}{print}' infile > outfile

でoutfileに出力すると、文字列1、文字列2の指定に応じて実際のoutfileの内容は以下のようになりました。

# RS ORS 実際のoutfileの内容
1 無指定 無指定 1行目[LF]
2行目[LF]
2 無指定 ORS="\n" 1行目[LF]
2行目[LF]
3 無指定 ORS="\r\n" 1行目[CR][LF]
2行目[CR][LF]
4 RS="\n" 無指定 1行目[LF]
2行目[LF]
5 RS="\n" ORS="\n" 1行目[LF]
2行目[LF]
6 RS="\n" ORS="\r\n" 1行目[CR][LF]
2行目[CR][LF]
7 RS="\r\n" 無指定 1行目[LF]
2行目[LF][LF]
8 RS="\r\n" ORS="\n" 1行目[LF]
2行目[LF][LF]
9 RS="\r\n" ORS="\r\n" 1行目[LF]
2行目[LF][CR][LF]

自分はgawkの動作を以下のように考えていました。

  1. infileを先頭文字から読む
  2. RSで指定されたパターンが現れるとそのパターンの前までの文字列を1行と認識
  3. 1行と認識した文字列の末尾にORSで指定された文字列を付けて出力

これが正しいとすると、#4〜#9の出力は以下のようになるはずです。

# RS ORS 想定されるoutfileの内容
4 RS="\n" 無指定 1行目[CR][LF]
2行目[CR][LF]
5 RS="\n" ORS="\n" 1行目[CR][LF]
2行目[CR][LF]
6 RS="\n" ORS="\r\n" 1行目[CR][CR][LF]
2行目[CR][CR][LF]
7 RS="\r\n" 無指定 1行目[LF]
2行目[LF]
8 RS="\r\n" ORS="\n" 1行目[LF]
2行目[LF]
9 RS="\r\n" ORS="\r\n" 1行目[CR][LF]
2行目[CR][LF]

しかし実際の出力とは異なります。
実際の出力を見ると、以下のように動いているような気がします。

  1. infileを先頭文字から読む
  2. [CR][LF]が現れると無条件で[LF]に変換する
  3. 変換後の文字を読んでいき、RSで指定されたパターンが現れるとそのパターンの前までの文字列を1行と認識
  4. 1行と認識した文字列の末尾にORSで指定された文字列を付けて出力

こう考えると#4,#5で[CR]が消えたり#7,#8,#9の1行目と2行目の改行コードが異なる理由も説明できます。
コメントされていた『cygwin自体でどうmountしているかということと』についてはbinmode,textmodeの両方でマウントした場合で同じ結果が出たので、mountが原因では無いのではと思っています。
……という訳なんですが、うまく伝えられてるかな。あ、Linuxでは試していないのでcygwin特有ではないかも知れません。