2017-03-20 24 views
1

更新:バッチファイルを使用してcsvファイルの行を解析する

私はcsvファイルを解析してその情報を使用したいと思います。ファイルを開く前の行の要素数はわかりません。私は行の数を知らない。最初にヘッダーを解析したいので、どのトークンを使用して行を解析するかを知ることができます。結果を行列形式で取得したいので、操作が簡単です。

また、後で結果をエクスポートするためにCSVを作成したいと思います。

私が解析したいcsvの例です(3行、10列に制限されています)。

"","rim_no","account_no","observation_date","observation_month","start_date","maturity_date","days_past_due","rate","spread" 
"1",2517,1000008332,20160831,201608,NA,NA,0,17,0 
"2",2517,1000008332,20160930,201609,NA,NA,0,17,0 

私は、行と列の数を事前に知っていません。私はまた、列の順序を知らない。私は口座番号、観測月、金利を計算したいと思います。最初にヘッダを解析して3,5,9の位置を取得したいので、他の行を解析するときにトークンとして使用できます情報

私が欲しいものの半分はやっていましたが、私が書いたコードはここにあります(今は読んで書いていますが、後で私が興味のある変数だけを残して、さらに計算します):

  • 私はもともと元だった:
    @ECHO off 
    SETLOCAL EnableDelayedExpansion 
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    ::Adress of the input and output files 
    
    GOTO InFile 
    
    :FalseIN 
    ECHO You need to enter a valid location for the source file. 
    GOTO InFile 
    
    :InFile 
    ECHO Please enter the location of your file in like C:\XXXX\YYYY\ZZZZ\example.csv 
    SET _fileIn 
    SET /P _fileIn=Type input: %=% 
    IF NOT EXIST "%_fileIn%" GOTO FalseIn 
    ECHO The selected input file to work with is %_fileIn% 
    
    :OutFile 
    ECHO Please enter the name of your output like C:\XXXX\YYYY\ZZZZ\output.csv 
    SET _fileOut 
    SET /P _fileOut=Type input: %=% 
    IF NOT EXIST "%_fileOut%" set "_fileOut=C:\XXXX\YYYY\ZZZZ\Output.csv" 
    ECHO.>"%_fileOut%" 
    ECHO The selected output file to work with is %_fileOut% 
    
    ECHO stop 1 
    @PAUSE 
    
    SET _ligne=0 
    SET _colonne=0 
    
    CALL :ParseHeader "%_fileIn%" 
    
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    
    GOTO :eof 
    ::Parse input file header, first element 
    :ParseHeader 
    SET /a _countParse+=1 
    SET _list=%1 
    SET _list=%_list:"=% 
    FOR /F "tokens=1* delims=, " %%a IN ('TYPE "%_list%"') DO (
        set _matrice[%_ligne%][%_colonne%]=%%a 
        set /a _colonne+=1 
        if not "%%b"=="" call :ParseHeaderBis "%%b" 
    ) 
    
    GOTO :eof 
    
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    
    GOTO :eof 
    ::Parse input file header, from second element onward 
    :ParseHeaderBis 
    SET /a _countParseBis+=1 
    SET _list=%1 
    SET _list=%_list:"=% 
    FOR /F "tokens=1* delims=, " %%a IN ("%_list%") DO (
        set _matrice[%_ligne%][%_colonne%]=%%a 
        if not "%%b"=="" set /a _colonne+=1 
        if not "%%b"=="" if %_ligne% equ 0 call :ParseHeaderBis "%%b" 
        if "%%b"=="" set /a _ligne+=1 
    ) 
    
    @PAUSE 
    
    IF %_ligne% gtr 0 GOTO :EchoHeader 
    
    GOTO :eof 
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    
    :EchoHeader 
    FOR /L %%H IN (0,1,%_colonne%) DO (
        echo|set /p=!_matrice[0][%%H]!>>%_fileOut% 
        if not %%H equ %_colonne% echo|set /p=,>>%_fileOut% 
        if %%H equ %_colonne% echo.>>%_fileOut% 
    ) 
    
    @PAUSE 
    
    CALL :Next 
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    
    GOTO :eof 
    ::Parse input file data, from second row onward, get lines 
    :Next 
    SET /a _countNext+=1 
    SET /a _ligneAct=%_ligne% 
    SET _colonne=0 
    FOR /F "skip=%_ligne% tokens=* delims=" %%a IN ('type "%_fileIn%"') DO (
        if not "%%a"=="" call :NextBis "%%a" 
        if "%%a"=="" goto :eof 
    ) 
    
    GOTO :eof 
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    
    GOTO :eof 
    ::Parse the lines from the input file 
    :NextBis 
    SET /a _countNextBis+=1 
    SET _list=%1 
    SET _list=%_list:"=% 
    FOR /F "tokens=1* delims=, " %%a IN ("%_list%") DO (
        set _matrice[%_ligne%][%_colonne%]=%%a 
        if not "%%b"=="" set /a _colonne+=1 
        if not "%%b"=="" if %_ligne% equ %_ligneAct% call :NextBis "%%b" 
        if "%%b"=="" set /a _ligne+=1 
    ) 
    
    IF %_ligne% gtr %_ligneAct% GOTO :EchoData 
    
    GOTO :eof 
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    
    :EchoData 
    SET _var="" 
    FOR /L %%H IN (0,1,%_colonne%) DO (
        if %%H equ 0 set _var=!_matrice[%_ligneAct%][%%H]! 
        set _help=!_var! 
        if %%H gtr 0 set _var=!_help!, !_matrice[%_ligneAct%][%%H]! 
        echo !_var! 
        if %%H equ %_colonne% echo !_var!>>%_fileOut% 
        ::echo|set /p=!_matrice[%_ligneAct%][%%H]!>>%_fileOut% 
        ::if not %%H equ %_colonne% echo|set /p=,>>%_fileOut% 
        ::if %%H equ %_colonne% echo.>>%_fileOut% 
    ) 
    
    @PAUSE 
    
    CALL :Next 
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    
    :eof 
    @PAUSE 
    

    ブーティは、まだ二つの問題を持っています私は :EchoHeaderと同じ方法ですべての移植を行っていますが、これは非常に遅いので、最初に 要素を連結し、行全体をアウトシートします(EchoDataを参照)。問題は です。エラーが発生し、エクスポートできません。私は理由を知りません。私がエコーするとき !_var! の私のforループの最後の3行のコメントを外してください:EchoData、私は_varが私の望むものだとわかりますが、コメントしたときには バグだけです。

  • 何もない場合でも次/次のbisループが実行されている
    私はgoto:eofがこれを避けると思ったが、私は が明らかに何かを見逃していた。

ご協力いただければ幸いです。

PS:私は私のコードが最適であるとは思わない、実行中の時間を改善するための任意のアイデアも歓迎です:)

+0

を示すべき?入力されたCSVファイルはどのように見えますか? – aschipfl

+0

おかげで、私はそれを忘れてしまった、今の '%=%'接尾辞である何 – Didifr

+0

が追加されますか?また、サンプル出力ファイルと関連ユーザー入力も提供してください。定義されていない場合は、「_fileOut =詐欺」 '(あなたは変数が空であるかどうかを確認したいと仮定)を設定_fileOut定義されていなければちなみに、ラインは'「%の_fileOut%」を設定する「_fileOut = conが」 '実際に'お読みください。 ... – aschipfl

答えて

0

サブルーチン/関数は、コードを構造化する素晴らしいものですが、:

  • あなたはプログラムフローが誤ってそれらに流れ込まないように注意しなければなりません。 goto :eofを手前に挿入します。
  • サブ/関数の最後にもgoto :eofを挿入して、呼び出し側に制御を戻します。
  • あなたが何をするか分からない限り、ラベルの内部コードブロックは使用しないでください。使用のREMは、代わりに
  • は、単にあなたが再帰的に、異なる引数の型、一度ファイル名とヘッダの残りの部分でParseHeaderを呼び出すように見えるset /P "header="<infile.txt
  • を使用したファイルの最初の行を読むために(%% B)
  • 内部いただきました!見て、set _matrice一時停止する前に、あなたの2次元_matrice問題の中間結果を表示します。

これは本当に答えではないが、はるかにコメントに入れて。

  • エラーが発生しやすい手動のユーザー入力ではなく、ファイルピッカーでvbs/PowerShell関数を使用できます。
  • 他のヘルプにあなたを助けるために、あなたはとのトラブルを正確に何を持っているか調べたいとあなたが(例えば整列列)を期待するものつながる典型的なCSV
+0

ありがとう: - 追加のgoto:EOFの前に&Iはそれができますなぜ私が得ることを確認していないものの、後。 - 変更されました:: rem。繰り返しますが、どのように役立ちますか?私はまだコメントを見て解釈します。 - ファイルのアドレスについてユーザーに問い合わせると、そのアドレスと名前は不明です。それを行うためのより良い方法で来ることができませんでした。 - 列数が不明なので再帰的に解析します。最初の要素(存在する場合)を読み込み、行の終わりまでテストします。 – Didifr

関連する問題