Look on the Bright Side of Things

Anderson's Blog - since 2005

Rubyでデータ抽出

Rubyを触って2日目。前回の続きで、CSVファイルの整形。SQL-SEVERからBCPで吐かれたデータには不要なものが混じってる。SQLで取り除いておけばいいだけの話だが、Viewをなるべく作りたくないし、BCPのFMTファイルをあんまりいじりたくないのでRubyで抽出する。つっても大したことは全然無い。
同様なデータが幾つかあるので、バッチファイルに組み込む際、引数で使い回せるようにした。

=begin
  kill_Stat_D.rb 引数1 引数2 引数3

  Status1 = A の明細のみ抽出する
  Status2 != null も抽出する(オプション)

  引数1…ファイル名(pathは有害不要)
  引数2…Status1の項目順序。内部で配列に合わせるので実際の位置でよい
  引数3…Status2の項目順序。必要な時に
=end
# =begin 〜 =end でその間はコメントアウトできる。

filname = ARGV[0]
st1 = ARGV[1]
st2 = ARGV[2]
# ARGVってのが引数。スペースで区切って指定すると配列として読み込める

ohead = "wk_"

# 引数指定がないと終わり
unless filname
  exit
end

unless st1
  exit
end

wf = open(ohead + filname,"w")

# 本当はオープンエラーも考慮すべきだが、まだ勉強途中なのでパス
open(filname){ | rf |
  while line = rf.gets do
    arr = line.split(/,/)
    
    unless st2
    # 読んでそのまま、引数2がなかったら下の処理、有ったらelseへ。わかりやすい。
      if arr[st1.to_i - 1] == "A"
         # ARGVでわたされた引数はString扱いなので、to_iで整数に変換
         # VBの癖で比較をついつい" = " で書いてしまう。
        wf.print line
      end
    else
      if arr[st1.to_i - 1] == "A" && arr[st2.to_i - 1]
        wf.print line
      end
    end
  end
}

wf.close

ファイルのOpen方法を前回と変えてみた。これだと自動的にCloseしてくれるので、Close忘れの心配がない。Perlとかやってて好きなのは、いちいち真偽を比較しなくて良いところ。下記のようなのがいいのだ。例えばある変数が0になったら抜けるループだと、

# Perlとかの場合
$a = 10
while($a){
 $a--;
}

'VBだと冗長、しかもtrueは-1だから上のようには書けない
dim a as int
a = 10
while a > 0 do
  a = a - 1
loop

記述は簡素かつ意味が取りやすい方が書いてても読んでても楽。
次はテキストファイルのソートをどうするか考え中。