• ベストアンサー

テキスト行頭の数字文字列の欠番、重複を発見するツールを見つけています

テキストで行頭に行番号のように半角数字が任意の桁数で付いているデータがあります。 数字の後に半角スペースに続き任意のテキストデータが続いています。 このデータはソートしてあるものとします。 このデータの(行番号)の幾つかが欠落していたり重複している物とします。 このデータの欠番や重複を発見するツールを見つけたいのですが何かありますか? やはり特殊な用途なのでBASICなどで自作する必要があるのでしょうか? 当方、一応コマンドラインツールは使えますが出来ればWindows環境で処理したいです。 処理速度も速い方が望ましいです。 エディタは秀丸を使っていますがマクロ作成能力はありません。 データ量は数MB程度です。

質問者が選んだベストアンサー

  • ベストアンサー
  • SHIMAPEE
  • ベストアンサー率75% (154/203)
回答No.2

WSH(Windows Script host) JScriptで作ってみました。SequenceCheck.jsなどの名前を付けて保存し、ダブルクリックで実行して下さい。出力ファイルにエラーの行を書き込みます。出力の形式はお好みですが、 「入力ファイル名(行番号): マーク 該当行」 にしました。こうすれば出力ファイルを秀丸エディタで開き、F10キーで入力ファイルにタグジャンプできます。 マークは下記にしてみました。 ★ : 重複しています。 ☆ : 欠番があります。 ? : 行頭の数字と空白がありません。 ----- // SequenceCheck.js var Ifile="C:\\SeqInput.txt"; // ★ 入力ファイル名。お好みで書き換えて下さい var Ofile="C:\\SeqOutput.txt"; // ★ 出力ファイル名。お好みで書き換えて下さい var Fs=WScript.CreateObject("Scripting.FileSystemObject"); var ForReading=1, ForWriting=2; var Itxt, Otxt, Line, LineNo=0, CurrSeq, PrevSeq=-1; var re=/^([0-9]+) /; // 行頭の任意の桁数の1バイト数字と1バイトの空白の正規表現 Itxt=Fs.OpenTextFile(Ifile, ForReading); Otxt=Fs.OpenTextFile(Ofile, ForWriting, true); while(!Itxt.AtEndOfStream){ Line=Itxt.ReadLine(); LineNo++; //if ((LineNo % 20000)==0) // 20000行毎にメッセージを出す // WScript.Echo(LineNo+" 行目をチェック中です。"); if (Line.match(re)!=null){ // 行頭の数字と空白があれば CurrSeq = parseInt(RegExp.$1,10); // 10進数に変換する if (PrevSeq!=-1){ // 先頭行でなければチェックする if (PrevSeq==CurrSeq) Otxt.WriteLine(Ifile+"("+LineNo+"): ★ "+Line); // 重複しています else if ((PrevSeq+1)!=CurrSeq) Otxt.WriteLine(Ifile+"("+LineNo+"): ☆ "+Line); // 欠番があります } PrevSeq = CurrSeq; } else Otxt.WriteLine(Ifile+"("+LineNo+"): ? "+Line); // 数字と空白がありません } Itxt.Close(); Otxt.Close(); WScript.Echo ("チェックが終わりました。"); // ここまで

fuk22
質問者

お礼

無事、4万行余りのうち948個の欠番を見つけることができました。 処理速度も満足しています。 やはり汎用のツールは無いので自作という事になるのでしょう。 ありがとうございました。

その他の回答 (2)

回答No.3

ANo1 の者です。 結構たくさんの欠番があるようですね。 イメディエイトウィンドウって、何byte か何行かわかりませんが、さかのぼって見ることができる範囲に限度があって、最初の方に出力した内容は消えてしまってるようですね。 Excel だったら結果をシートに出力するとか、あるいは、ファイルに出力するとか、改良された方がいいみたいですね。

回答No.1

VBA でしたら、例えばこんな感じでできます。 ( 結果はイミディエイトウィンドウに出力しています。) Private Sub CommandButton1_Click() Dim iFileNo As Integer Dim strLine As String Dim iSpacePos As Integer Dim lngLineNo As Long Dim lngPrevLineNo As Long Dim lngDuplication() As Long Dim lngNotExist() As Long Dim lngDupCnt As Long Dim lngNotExistCnt As Long Dim l As Long iFileNo = FreeFile Open "C:\Test\Data.txt" For Input Access Read As iFileNo lngPrevLineNo = 0 Do Until EOF(iFileNo) Line Input #iFileNo, strLine iSpacePos = InStr(strLine, " ") If iSpacePos <> 0 Then strLine = Left(strLine, iSpacePos - 1) End If If IsNumeric(strLine) Then lngLineNo = CLng(strLine) If lngLineNo = lngPrevLineNo Then '重複している ReDim Preserve lngDuplication(lngDupCnt) lngDuplication(lngDupCnt) = lngLineNo lngDupCnt = lngDupCnt + 1 ElseIf lngLineNo <> lngPrevLineNo + 1 Then '欠番 For l = lngPrevLineNo + 1 To lngLineNo - 1 ReDim Preserve lngNotExist(lngNotExistCnt) lngNotExist(lngNotExistCnt) = l lngNotExistCnt = lngNotExistCnt + 1 Next l lngPrevLineNo = lngLineNo Else lngPrevLineNo = lngLineNo End If End If Loop Close iFileNo Debug.Print "重複データ" For l = LBound(lngDuplication) To UBound(lngDuplication) Debug.Print lngDuplication(l) Next l Debug.Print "欠番データ" For l = LBound(lngNotExist) To UBound(lngNotExist) Debug.Print lngNotExist(l) Next l End Sub

fuk22
質問者

お礼

夜遅く、とても具体的なソースのご提供ありがとうございました。 VBAを触るのは久しぶりなのでかなり手こずりました。 手元のExcel97で実行させると私の環境では欠番データの最後の200個だけが出力され、それ以前のデータは出力されません。

関連するQ&A