プロが教える店舗&オフィスのセキュリティ対策術

巨大なCSVの加工(指定列のみの抽出)について

下記のような構成のCSVファイルがあります。

"ID","a","b","c","d","e","f","g","h","i","j","k","l","m"
"0001","a","b","c","d","e","f","g","h","i","j","k","l","m"
"0003","a","b","c","d","e","f","g","h","i","j","k","l","m"
"0004","a","b","c","d","e","f","g","h","i","j","k","l","m"




例えば、
ここから"ID"列と"c"列と"f"列のみ抽出して新たなCSVファイルで保存。
という処理を行いたいのですが、行数が5000万行近くあり、ファイルサイズが80GB程あるので
エクセルはおろかアクセスでも開くことができません。
テキストエディタの秀丸64bit版なら開くことができますが、指定列の抽出方法が分かりません。
秀丸のマクロでもVBSでも良く、また膨大な待ち時間がかかっても構わないので実現する方法について
お知恵をお貸しください。

A 回答 (5件)

"ID","a","b","c","d","e","f","g","h","i","j","k","l","m"


"0001","a","b","c","d","e","f","g","h","i","j","k","l","m"
扱いやすいように仕向けるのも手段の一つ。
"ID00","a","b","c","d","e","f","g","h","i","j","k","l","m"
"0001","a","b","c","d","e","f","g","h","i","j","k","l","m"
固定長になるものであれば
C列相当は16文字目から3バイト
F列相当は28文字目から3バイト

実際は固定長ではないのだろうが、
プログラムができるのなら、
そのプログラム技術で取り込みやすいデータに
加工することもできるのではないか。そういう工夫できることはないか。
最終目的でなくても何かできないか探してみる。
・・・のキーワードの後20バイトにC列とF列が
含まれているはず、となればその20バイトだけ抜き出すことで
扱うサイズがグッと減る。
工夫したければ、何か規則性を探す。

1行ずつ読み込んで判定を繰り返すプログラムで十分かと思います。

エクセルにろアクセスにしても
シートやテーブルに格納するだけが手段ではない。
VBAを使えばファイルI/O操作はできます。
    • good
    • 2

VBAでもVBSでもかんたん。


No1の方の書いたとおりにやればできる。
ボクだったら、古典的(失礼)ファイルの開き方の代わりにFileSystemObjectを使うといっただけ。
丸投げは嫌いだから、デバッグしないで載せちゃうけど、こんな感じ

dim fso as new filesystemobject
dim ts1 as textstream
dim ts2 as textstream
dim a as variant
set ts1 =fso.opentextfile("hogehoge.csv",forreading,false)
set ts2 =fso.opentextfile("hogehogeout.csv",forappending,true)
do while not ts1.atendofstream
a = split(ts1.readline,""",""")
ts2.writeline a(0) & """,""" & a(3) & """,""" & a(6) & """
loop
ts1.close: set ts1 = nothing
ts2.close: set ts2 = nothing
set fso = nothing

メンセキジコウ  一応私の知識の範囲で間違いのないよう書いたつもりですが、、、
・vbaもしくはvb6で動くように書いたつもりです。
・デバッグしていないのでエラーが起きる可能性があります。
・ファイルの破損等、不測の事態に対しては責任を負えませんので、バックアップなりコピーとるなりして試してみてください。
・実際に動かすときは、カウンターを組み込んで進捗状況がわかるように知るべきだと思います。
・まずは一万件くらいからやってみて、どのくらい時間がかかるか想定してからやったほうが良いと思います。
・filesystemobjectを使うためには参照設定で、windows scripting runtimeにチェックを入れる必要があります。


余計なことだけど、
・実質6行のプログラムだよ。質問する間に書けちゃうけど、仕事じゃないよね。
・No1さんが手順をきっちり書いてるけど、少しは調べてみたのかな? 
・作ったファイルだって読める代物じゃないと思うけど、どうすんの?→機械で処理するならそちらの処理側に書いたほうがいいじゃないかな?

この回答への補足

まだ理解できてませんが、徐々に調べて進めていきたいと思います。

私はプログラマではありませんので先の方が回答してくださった手順は考え方は理解できましたが、
だからといってどう実現すべきかは分かりませんでした。
しかし具体的なソースを見せていただけて助かります。
もちろん自己責任ということを承知の上ですのでご心配なく。

補足日時:2011/04/20 15:38
    • good
    • 0

(大体件数的に読めないデータを何のために使うのかという問題はさておき)


データを見るからにはきっと何らかのDBから落としたもんなんだよね。
ってことは、DBを操作してほしいデータを抽出しなおすのが本筋。

DBへのアクセス権限がないのであれば、私だったら、fsoのreadlineをつかうかな。
何回もいろんな形で操作する必要があるなら、また、別のDBに突っ込んじゃうとか、
アクセスなどで、リンクテーブル作っちゃうとか言う方法もあるけど。

この回答への補足

件数は5000万件と申し上げております。
アクセスのリンクテーブルでも大きすぎて取り込めなかったはず?(もう一度試してみますが)

カンマ区切りで何番目と何番目と何番目をこのファイルに書き込む、という動作を
1行ずつ最終行まで延々と繰り返すような簡単なロジックで
VBS等で簡単に実現できないでしょうか。
ごく一般的な環境で実現可能な案があれば教えてください。

補足日時:2011/04/20 13:31
    • good
    • 0

フィールド内に改行を含むような場合はPerlの「Text::CSV_XS」モジュール、Rubyの「CSV」モジュールを使った方が圧倒的に楽です。


http://www.ruby-lang.org/ja/man/html/CSV.html
    • good
    • 0

何も悩むことはない。

一旦全レコードを読み込んで処理というエクセル的固定観念に毒されている。昔は1レコードを読んで処理が主流だったのだ。VBAでもVBSでもVB.NETでも旧Basicでもよい下記のためのステートメントがある。
(1)ファイルをオープン(インプトファイルとアウトプットファイル各1つ)
(2)テキストを1レコード読み込む
(3)そのテキストを、カンマをデリミタとして、分離し配列に収納。Split関数利用
(4)第1列、C列、F列(配列インデックスでは0、2、5について新しいファイルに書き出す
(5)EOFまで繰り返し
(6)AT ENDでファイルをクローズ。
Googleででも「VBA テキストファイル オープン」「VBA テキストファイル 読む」「VBA Split関数」「VBA テキストファイル 書く」
などで照会し、勉強すること。
時間はかかるがやむをえない。。全レコーど対象のようだから1回は全レコード読まなければしょうがない。
そもそも3列のファイルをわざわざ作らなくても、別途何か本当の処理するときに他の列を使わなければ仕舞いのようにも思うが。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています