April 27, 2007

Process Substitution

zshやbashにはProcess Substitutionという機能が備わっていて、これを使うことで一時ファイルを経由せずにプロセス間でやりとりできる。

例えば、あるログからgrepで必要な部分だけを取りだし、またもう一方のログからもgrepで必要な部分だけを取り出して、双方のdiffを取る、という処理をする場合に、これまで一時ファイルを作成してdiffを取っていた。ところが

$ diff -u <(grep foo foo.log) <(grep foo bar.log)

これだけでいいらしい。たいへん衝撃的な出来事だった。
裏では何が行われているかというと、それぞれの出力先fdを/proc/self/fd/nとしてdiffに渡している。

ちなみに、>(process)で出力として使える。

$ grep blog.tagoh.jp /var/log/apache2/access.log | tee >(grep -E '(google|yahoo)' > foo) | grep -v -E '(google|yahoo)' > bar

まあこんなことは普段しないし、しようとも思わないんだけど、出力を何種類かにわけて異なる処理をしたい場合に便利かもしれない。

April 13, 2007

webからテキスト部分だけを抽出する

要件は次のとおり。

  • 整形されてないテキストがほしい
  • 後にkakasiとかでローマ字に分解したいので、もともとASCII文字であるものを区別したい

他にももっとうまい手がありそうだけど、とりあえず以下で落ち着いた。

#! /bin/sh

w3m -dump_source $1 | nkf -w | sed -n -e "/<body.*>/!{x;/<body.*>/{x;\,</body>,{q};s/&nbsp;/ /g;s/<[^<>]*>//g;s,\([-0-9a-zA-Z ().!\"#$%&=^~\\|\`@{};:+*,<>/?_'[]]*\),<ASCII>\1</ASCII>,g;s,<ASCII></ASCII>,,g;s,</ASCII><ASCII>,,g;/^$/{d};p};d};/<body.*>/{h}"


実体参照の置換は他にも必要になるだろうけど、まあそれはそれで。