csvファイルで、特定の行のみ削除する簡易な方法について質問致します。


今、約10万行×500列(コンマ区切り)のcsvファイルがあります。
特定の行を削除したいのですが、削除したい行は複数(数千)あります。
行番号は全てわかっています。

申し訳ないですが、ExcelやAccessを用いないで削除を実現する簡易な方法
をご教授頂ければ幸いです。
(コマンドプロンプト等はOK、フリーソフトは数十~百MBのcsvファイルでも
 問題なく動いてくれればOK、その他いい方法があれば何でも!)

どうぞよろしくお願い致します。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2010/05/03 05:23:06
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:chyopper No.1

回答回数416ベストアンサー獲得回数69

ポイント50pt

以下のスクリプトを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
id:miku1973

ありがとうございます!上手くいけそうです。いるか贈ります!

2010/05/03 05:20:57

その他の回答3件)

id:chyopper No.1

回答回数416ベストアンサー獲得回数69ここでベストアンサー

ポイント50pt

以下のスクリプトを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
id:miku1973

ありがとうございます!上手くいけそうです。いるか贈ります!

2010/05/03 05:20:57
id:lizy No.2

回答回数45ベストアンサー獲得回数14

ポイント15pt

スクリプト(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

id:miku1973

ありがとうございます!やってみます!

2010/05/03 05:21:25
id:TREEG No.3

回答回数255ベストアンサー獲得回数34

ポイント15pt

私も時々数百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

id:miku1973

ありがとうございます!perlをインストールしていないのですが、機会があれば朝鮮します。

2010/05/03 05:21:59

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 kick_m 1372 1033 54 2010-04-27 13:08:57

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません