Wed, 10 Dec 2008 (平成20年) [長年日記]
_ 本日のワンライナー
またワンライナーのお世話になった。ちょっとしたデータ処理にけっこう使う場面は多いのではないかと思うのでやったことをまとめておくと未来の自分に役立ちそうだから記録しておく。
今回は五十ほどのファイルに分かれている、タブで区切られたデータの整理が目的。データはこんな感じ。必ずしもすべての項目が埋まっているわけではない。
1279 FG01105 20081013 1500 1700 9000072 fuga 111 -1 1280 FG01112 20081014 1300 1500 hogehoge 004 1 1281 FG01108 20081015 0630 0800 foobarfoo 005 0 1282 FG01115 20081015 0800 1700 uzura sixamo 003 -1 1283 FG01105 20081015 1700 2000 7659393 byebye 410 0
やりたいことは最後の項目を調べて -1 以外の行だけピックアップすること。基本は前回で理解できてたので十分ほど試行錯誤してこう書いた。
ruby -i.bak -ane 'puts $_ unless $F[-1] == "-1"' *.tsv
- -i.bak
- 拡張子を bak にして元のファイルを残す。
- -a
- オートスプリットモードを ON に。「$F = $_.split が実行される」と書いてあるので使ってみたら、連続したタブはまとめられてしまうけど、特に指定しなくてもタブで区切ってくれたので今回はうまいこといった。
- -n
- 前回は元データの各行はそのまま出力する必要があったから各ループの最後に変数 $_ の値を出力してくれる -p を使ったけど、今回はそれでは困るのでこっちのオプションを使用。
詳しくは Ruby リファレンスマニュアルに。
以前に同じ作業をした時にはめんどくさいと思いながら Excel でごにょごにょと手作業したけれど、今回はなんと楽だったことか。
_ ちょっと応用
「最後の項目が -1 以外の行のうち、六個目の項目が空でない行だけピックアップ」だとしたら、連続したタブでも一つずつ区切り文字にしたいわけで、こうしてみたけどうまくいかない。
ruby -i.bak -ne '$F = $_.split(/\t/);puts $_ unless ($F[-1] == "-1" or $F[5] == "")' *.tsv
最後の項目が -1 の行が除外されない。なぜだ。irb で
a = "1279\tFG01105\t20081013\t1500\t1700\t9000072\t\tfuga\t\t111\t-1";$F = a.split(/\t/);puts a unless ($F[-1] == "-1" or $F[5] == "")
を実行したら想定どおりに動くのに。
_ 原因判明
ruby -i.bak -ne '$F = $_.split(/\t/);puts $F'
を実行したら原因がわかった。$F[-1] に最後の項目だけでなく \n まで含まれていたからだった。
ということで、
ruby -i.bak -ne '$F = $_.chomp.split(/\t/);puts $_ unless ($F[-1] == "-1" or $F[5] == "")' *.tsv
_ 月刊 Microsoft Update
もう来た。XP SP3 の MS Office なしで六個。職場で実行して問題がなかったらこっちも、のつもりなのであとで。
_ 11 月公開の PDF のぜい弱性は攻撃コード作成が容易,速やかに更新を
何がどうなっているのかの解説は初めてみた気がするのでメモ。