木っ端拾いの材木流し

Cannot see the wood for the trees.

Cygwin上のAWKでの改行コードの扱われ方

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

すっきりしてないのですが、改行を含めて Unix 系 OS と同じにするなら BINMODE で実行するのが望ましいのかもしれません。

特定の文字列を含むセクションだけを抜き出す (続き) - 日本 GNU AWK ユーザー会 0.2

情報ありがとうございます m(_ _)m CygwinだけでなくGAWKにもBINMODEというのがあったのですね。調べてみたらGAWKのドキュメントに記述がありました。

Under OS/2 and DOS, gawk (and many other text programs) silently translate end-of-line "\r\n" to "\n" on input and "\n" to "\r\n" on output.

http://www.kt.rim.or.jp/~kbk/gawk-3.1/gawk.html#SEC257

Cygwin上のGAWKを「Under OS/2 and DOS」と呼んでいいか微妙ですが、GAWKが"\r\n"を"\n"に変換しているようです。で、BINMODE=rとすると入力ファイルの改行コードをそのままGAWKで処理すると。勉強になりました。
(10/19追記)
AWKの偉い人らしいきむらさん*1が調査結果を公開されていました。ありがとうございます。
本当はちゃんと書きたかったのですが時間がないため簡単なご紹介のみでご容赦下さい。

手順としては

  • Cygwin上のCプログラムで入力の改行コードが自動変換されることを確認
  • AWKデバッグモードで動かして、最初の入力時点で改行コードが自動変換されることを確認
  • ソースを追いかけてlibcが原因と特定

という流れです。
問題解決力の高さは問題を切り分ける分解能の高さからくるんだなと感じます。

*1:よく見たら上のGNU Awk ユーザーズガイドの訳者さんじゃないか!

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

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

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特有ではないかも知れません。

基礎から始めるデータベース入門セミナー

オラクル通信の連載。オラクル社のサイトにはバックナンバーへのリンクも連載の一覧も無いので勝手にリスト化。

*1:ラクル通信のタイトルは「Structured Query Language(SQL)とは?」となっているが第5回タイトルの誤植と思われるため編者により修正

*2:こっちは誤植ではない。内容がループしてるのか?

「ニンテンドーDSブラウザ」は携帯ゲーム機をPDAに進化させるかも

ちょっと古いニュースですが、ニンテンドーDS向けブラウザが出るそうです。
ニンテンドーDSブラウザー - えむもじら

最初は余り気にならなかったのですが、関連する次の記事を読んで印象がかなり変わりました。
革命的デバイス - いつか作ります - 断片部

単なるブラウザだと考えると「ブラウザにわざわざ金を払うの?」とか「他の事をする時は結局カセットを入れ換えなきゃならないじゃない」と思うわけですが、ブラウザ上で動く数々のWebサービスがDSで使えると考えれば、色々な使い道が考えられます。
PDAの代表的な機能であるスケジュール管理、アドレス管理等を行うWebサービスは既に存在しますし、Flash等で作られたゲームをDSで遊ぶ事もできるかも知れません。

当面のポイントは

  • JavaScript,Flash等のクライアントサイド技術にどの程度対応しているか
  • DSの操作感を活かしたコンテンツが提供されうるか

といった所でしょうか。

というわけで、マージンFXのひまわり証券さん、ニンテンドーDS Lite欲しい!<結局それかよ

Google ニュース 日本語版 の RSS/Atom フィードが配信停止に

4/7にGoogle ニュース 日本語版で検索結果のRSS/Atomフィード配信が始まったのですが、1日足らずで配信が停止されてしまったようです。
また、昨年8月から既にフィード配信に対応していた英語版の方も、フィードへのリンクが無くなってしまっています。
Google ニュースは立ち上がりの時もひと悶着あったので、今回も新聞社からのクレームがあったかどうか気になる所です。
立ち上がりの時は収集を拒否した新聞社がGoogle ニュースの集客力に負けて最終的には収集されるようになったと記憶しています。
今回もフィードを受け入れる所と受け入れない所を明記した上で受け入れた所のみフィードを配信するようにすれば良いのではないかと思いました。
関連:Google ニュース 日本語版 の RSS/Atom 配信が一晩で停止に? : 管理人@Yoski

Powerpoint で縦書きテキストボックス内の数字が縦書きにならない

Powerpointで縦書きテキストボックスに半角数字を書くと、

20

06

のように2文字ずつ横書きで表示されてしまいます。
これを縦書きに直すには、ツールバーのユーザー設定で追加できる横組みボタンを使う必要があります。
参考:http://office.microsoft.com/ja-jp/assistance/HP052507831041.aspx