«前の日記(Tue, 09 Dec 2008 (平成20年)) 最新 次の日記(Thu, 11 Dec 2008 (平成20年))» 編集 RSS with tsukkomi RSS without tsukkomi

実験的「実験的日記」


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 のぜい弱性は攻撃コード作成が容易,速やかに更新を

何がどうなっているのかの解説は初めてみた気がするのでメモ。

目次

«前の日記(Tue, 09 Dec 2008 (平成20年)) 最新 次の日記(Thu, 11 Dec 2008 (平成20年))» 編集