今、約10万行×500列(コンマ区切り)のcsvファイルがあります。
特定の行を削除したいのですが、削除したい行は複数(数千)あります。
行番号は全てわかっています。
申し訳ないですが、ExcelやAccessを用いないで削除を実現する簡易な方法
をご教授頂ければ幸いです。
(コマンドプロンプト等はOK、フリーソフトは数十~百MBのcsvファイルでも
問題なく動いてくれればOK、その他いい方法があれば何でも!)
どうぞよろしくお願い致します。
以下のスクリプトをtest.vbsで保存
コマンドプロンプトでスクリプトを実行します。
c:\>cscript test.vbs
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") Const ForReading = 1, ForWriting = 2, ForAppending = 8 Set objInput = objFSO.OpenTextFile("test1.csv", ForReading) ' 入力csv Set objOutput = objFSO.OpenTextFile("test2.csv", ForWriting, True) ' 出力csv Do Until objInput.AtEndOfStream ' 入力ファイルの終端まで繰り返し srhFlg = 1 strLine = objInput.ReadLine ' 入力ファイルを1行読み込む Set objMask = objFSO.OpenTextFile("del.txt", ForReading) ' 削除行入力ファイル Do Until objMask.AtEndOfStream strMask = objMask.ReadLine If StrComp(objInput.line-1, strMask ) = 0 Then '入力ファイルと削除行の比較 srhFlg = 0 End If Loop If srhFlg = 1 Then ' 指定行は出力しない objOutput.WriteLine strLine End If srhFlg = 1 Loop objInput.Close objOutput.Close objMask.Close
削除行の指定はdel.txtに記入します。
例
1 3 29
以下のスクリプトをtest.vbsで保存
コマンドプロンプトでスクリプトを実行します。
c:\>cscript test.vbs
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") Const ForReading = 1, ForWriting = 2, ForAppending = 8 Set objInput = objFSO.OpenTextFile("test1.csv", ForReading) ' 入力csv Set objOutput = objFSO.OpenTextFile("test2.csv", ForWriting, True) ' 出力csv Do Until objInput.AtEndOfStream ' 入力ファイルの終端まで繰り返し srhFlg = 1 strLine = objInput.ReadLine ' 入力ファイルを1行読み込む Set objMask = objFSO.OpenTextFile("del.txt", ForReading) ' 削除行入力ファイル Do Until objMask.AtEndOfStream strMask = objMask.ReadLine If StrComp(objInput.line-1, strMask ) = 0 Then '入力ファイルと削除行の比較 srhFlg = 0 End If Loop If srhFlg = 1 Then ' 指定行は出力しない objOutput.WriteLine strLine End If srhFlg = 1 Loop objInput.Close objOutput.Close objMask.Close
削除行の指定はdel.txtに記入します。
例
1 3 29
ありがとうございます!上手くいけそうです。いるか贈ります!
スクリプト(JScript)を使うというのはアリでしょうか。
var stdin = WScript.StdIn; var stdout = WScript.StdOut; while (!stdin.AtEndOfStream) { if (isDeleteLine(stdin.Line)) { stdin.SkipLine(); } else { stdout.WriteLine(stdin.ReadLine()); } } function isDeleteLine(line) { // とりあえず3行目を削除 return line == 3; }
これを例えばremove.jsという名前で保存して以下のように実行すれば結果が得られます。
> cscript //nologo remove.js < input.csv > output.csv
ただ削除する行が多数になるようですので、指定方法を工夫する必要があるかもしれません(削除する行番号を書いたファイルを別途用意して、それで初期化するなど)
まあスクリプト内に削除する全行番号を書いてしまうことも不可能ではありませんがw
ありがとうございます!やってみます!
私も時々数百Mから1GB近いデータを扱いますが、perlをインストールして、perlでスクリプトを動かすのが一番楽だと感じています。
ちなみに、perlですと、こんな感じでできます。データ処理はMem-Ramなどに置いておくと早いですね。
#以下、kaiseki.plとしてファイルを作成して、解析したいCSVをtext.csvとする。perlのインストールがあれば、ダブルクリックで実行されます。
#削除したい行は、__DATA__の下に書く。例だと、1,4,10行を削除してくれる
my %line;
for(<DATA>){chomp;$line{$_}=1;}
my $f; my $w;my $cnt;
open($w,">>result.csv");
open($f,"<text.csv");</p>
while(<$f>){$cnt++;if($line{$cnt}){next;}print $w $_;}
close($f);
close($w);
__DATA__
1
4
10
ありがとうございます!perlをインストールしていないのですが、機会があれば朝鮮します。
回答者 | 回答 | 受取 | ベストアンサー | 回答時間 | |
---|---|---|---|---|---|
1 | kick_m | 1372回 | 1033回 | 54回 | 2010-04-27 13:08:57 |
ありがとうございます!上手くいけそうです。いるか贈ります!