2017-03-28 109 views
0

我的問題是,我可以迴應我想要的,但不是我想要的方式。儘管如此,取決於我如何編寫/安排代碼,我得到的迴應行爲不盡相同,從來沒有我想要的方式。有人可以解釋我發生了什麼,爲什麼結果如此,它可能會幫助我瞭解如何更改我的代碼以使其正確。這裏有一些解決方案(僅限於5),它然後如何表現(循環涉及所述第二線的回波):需要批處理文件(窗口)中的「回聲」的行爲

欲呼應矩陣的元素是(2行,逗號分割列)

, 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 
  1. 我想

什麼時候達到這個循環中,它只是退出並關閉命令窗口

: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!>>%_fileOut% 
  • 什麼工作,但速度很慢
  • 現在我的第一次嘗試,這是緩慢的,因爲它呼應元/逗號/元/逗號......到行前結束呼應換行符

    :EchoData 
    SET _var="" 
    FOR /L %%H IN (0,1,%_colonne%) DO (
    echo|set /p=!_matrice[%_ligneAct%][%%H]!>>%_fileOut% 
    if not %%H equ %_colonne% echo|set /p=,>>%_fileOut% 
    if %%H equ %_colonne% echo.>>%_fileOut% 
    ) 
    

    輸出看起來像

    , 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 
    
  • 奇怪的是,既相呼應我想要什麼樣的方式,什麼我不這樣做,並且是SLO w^
  • 闖闖,做工作,呼應結果兩次,第一次行緩慢的方式,第二排的快捷方式

    :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! 
    echo|set /p=!_matrice[%_ligneAct%][%%H]!>>%_fileOut% 
    if not %%H equ %_colonne% echo|set /p=,>>%_fileOut% 
    if %%H equ %_colonne% echo.>>%_fileOut% 
    ) 
    echo !_var!>>%_fileOut% 
    

    輸出看起來像

    , 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 
    1, 2517, 1000008332, 20160831, 201608, NA, NA, 0, 17, 0 
    
  • 奇怪的方式2
  • 另一種奇怪的方式,回聲行用逗號,然後兩次我的第二行

    :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 not %%H equ %_colonne% echo|set /p=,>>%_fileOut% 
    if %%H equ %_colonne% echo.>>%_fileOut% 
    if %%H equ %_colonne% echo|set /p=!_var!>>%_fileOut% 
    if %%H equ %_colonne% echo.>>%_fileOut% 
    ) 
    echo !_var!>>%_fileOut% 
    

    輸出看起來像

    , 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 
    1, 2517, 1000008332, 20160831, 201608, NA, NA, 0, 17, 0 
    
  • 變形奇怪的方式2
  • 當註釋一行,它只是退出腳本,不迴應任何東西......

    :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 not %%H equ %_colonne% echo|set /p=,>>%_fileOut% 
    if %%H equ %_colonne% echo.>>%_fileOut% 
    if %%H equ %_colonne% echo|set /p=!_var!>>%_fileOut% 
    if %%H equ %_colonne% echo.>>%_fileOut% 
    ) 
    echo !_var!>>%_fileOut% 
    
    Basically, I expected solutions 2,3,4 to behave as they do. 
    I would expect solutions 1 and 5 to behave differently (do not get what is wrong)... 
    Especially, I do not get why 3 and 4 do work but not 5 and 1. Is it something to do with the echo| set /p? 
    
    One more thing is that when echoing the slow way, element by element, it keeps returning "The system cannot find the drive specified". 
    

    爲了清楚的目的,我在這裏補充的完整代碼(輸入文件是上面提到的文件,在我的情況下,CSV):

    @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:\Users\VerchieD\Desktop\Command_line\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:\Users\VerchieD\Desktop\Command_line\output.csv 
    SET _fileOut 
    SET /P _fileOut=Type input: %=% 
    IF NOT DEFINED "%_fileOut%" set "_fileOut=C:\Users\VerchieD\Desktop\Command_line\Output.csv" 
    ECHO.>"%_fileOut%" 
    ECHO The selected output file to work with is %_fileOut% 
    
    ECHO stop 1 
    @PAUSE 
    
    SET _countParse=0 
    SET _countParseBis=0 
    SET _countNext=0 
    SET _countNextBis=0 
    SET _ligneAct=0 
    
    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 
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    ::Echoes one element at a time for now, will be changed 
    :EchoHeader 
    FOR /L %%H IN (0,1,%_colonne%) DO (
    ::echo The column %%H 
    ::echo variable is !_matrice[0][%%H]! 
    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 %%G IN (0,1,%_ligneAct%) DO (
    ::FOR /L %%H IN (0,1,%_colonne%) DO (
        ::echo The row %%G 
        ::echo and column %%H 
        ::echo value is !_matrice[%%G][%%H]! 
        ::if %%H equ 0 set _var=!_matrice[%_ligneAct%][%%H]! 
        ::set _help=!_var! 
        ::if %%H gtr 0 set _var=!_help!, !_matrice[%_ligneAct%][%%H]! 
        ::echo|set /p=!_matrice[%_ligneAct%][%%H]!>>%_fileOut% 
        ::if not %%H equ %_colonne% echo|set /p=,>>%_fileOut% 
        ::if %%H equ %_colonne% echo.>>%_fileOut% 
        ::if %%H equ %_colonne% echo|set /p=!_var!>>%_fileOut% 
        ::if %%H equ %_colonne% echo.>>%_fileOut% 
        ::if %%H==0 (set "_var=!_matrice[%_ligneAct%][%%H]!") else (set "_var=!_var!, !_matrice[%_ligneAct%][%%H]!") 
        ::echo !_var! 
    ::) 
    ::) 
    
    :: for /l %%c in (0 1 %col%) do (
    ::  if %%c==0 (set "line=!_M[%%r,%%c]!") else (set "line=!line!, !_M[%%r,%%c]!") 
    ::) 
    :: echo !line! 
    
    >%_fileOut% (
        ::for /l %%r in (0 1 %row%) do (
         set "line=" 
         for /l %%c in (0 1 %_colonne%) do (
          if %%c==0 (set "line=!_matrice[%_ligneAct%][%%c]!") else (set "line=!line!, !_matrice[%_ligneAct%][%%c]!") 
         ) 
         echo !line! 
        ::) 
    ) 
    
    ::echo !_var!>>%_fileOut% 
    @PAUSE 
    
    CALL :Next 
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    
    :eof 
    @PAUSE 
    
    +0

    你能不能解釋一下什麼是在%矩​​陣的計算方法%,%Colonne的%和% ligneAct%以及如何將值存儲在這些變量中?這會讓事情變得更清晰。 – Filipus

    +0

    基本上,我將我的值存儲在矩陣樣式中,以便於閱讀和瀏覽。 %_matrice%[] []是我創建的矩陣,%_colonne%是我期待的列,%_ligneAct%是我期待的實際行(行)。當我回聲時,我會經歷以下幾行:[0] [0],[0] [1],[0] [2] .... [0] [n]; [1] [0],[1] [1],[1] [2] .... [1] [n]; ...; [m] [0],[m] [1],[ m] [2] .... [m] [n] – Didifr

    回答

    1

    測試代碼

    @echo off 
        setlocal enableextensions enabledelayedexpansion 
    
        rem Populate "matrix" 
        set "row=-1" 
        for %%r in (
         "# ,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" 
        ) do (
         set /a "row+=1", "col=-1" 
         for %%c in (%%~r) do (
          set /a "col+=1" 
          set "_matrice[!row!][!col!]=%%c" 
         ) 
        ) 
    
        rem Dump "matrix" to output file 
        > "outputFile.txt" (
         for /l %%r in (0 1 %row%) do (
          set "line=" 
          for /l %%c in (0 1 %col%) do (
           if %%c==0 (set "line=!_matrice[%%r][%%c]!") else (set "line=!line!, !_matrice[%%r][%%c]!") 
          ) 
          echo !line! 
         ) 
        ) 
    

    對於爲什麼部分,速度問題的起源是因爲每個管道都會爲管道的每一側產生一個cmd進程。另外,重定向每個操作會使進程變慢,因爲它會爲每個操作打開/寫入/關閉輸出文件。只需重定向整個過程。

    你在你的輸出重複,因爲你是呼應相同的信息不止一次,通過set /p或直接與echo

    對於情況5,你一定不要使用::,使用註釋內的代碼塊行rem

    編輯更新,以遵循(超過更少)代碼的原代碼

    @echo off 
        setlocal enableextensions enabledelayedexpansion 
    
        set "inputFile=input.csv" 
        set "outputFile=output.csv" 
    
        rem Populate "matrix" 
        set "row=-1" 
        for /f "usebackq delims=" %%l in ("%inputFile%") do (
         set /a "row+=1", "col=-1" 
         set "line=%%l" 
         call :splitLine 
        ) 
    
        rem Dump "matrix" to output file 
        > "%outputFile%" (
         for /l %%r in (0 1 %row%) do (
          set "line=" 
          for /l %%c in (0 1 %col%) do for /f "delims=" %%x in ("!_matrice[%%r][%%c]!") do (
           if %%c==0 (set "line=%%x") else (set "line=!line!, %%x") 
          ) 
          echo !line! 
         ) 
        ) 
    
        type "%outputFile%" 
        goto :eof 
    
    :splitLine 
        (for /f "tokens=1* delims=, " %%a in ("!line!") do if not "%%a"=="" (
         set /a "col+=1" 
         set "_matrice[!row!][!col!]=%%a" 
         set "line=%%b" 
        )) && goto :splitLine || goto :eof 
    
    +0

    您的示例在獨立基礎上正常工作。儘管如此,當用最後一行代替我的行時,它會按照我的預期行事,它會退出腳本並關閉窗口而不將數據導出到文件。你的'if %% c == 1(設置「line =!_ M [%% r,%% c]!」)else(set「line =!line !,!_M [%% r,%% c]! 「)'與我的'if%%H equ equ 0 set _var =!_ matrice [%_ ligneAct%] [%% H]完全相同! set _help =!_ var! if %% H gtr 0 set _var =!_ help !,!_matrice [%_ ligneAct%] [%% H]!'給出了和我測試例子1-5時相同的結果 – Didifr

    +0

    @Didifr,我改變了該代碼符合你的語法,'_matrice [x] [y]'帶有0個基本索引。經過測試和工作。嘗試確保'col'和'row'的正確值。 –

    +0

    我不知道,它仍然不起作用。也許這將有助於看到整個代碼,我將編輯我的問題,添加缺少的部分,在其中構建我的矩陣,並按照我理解的方式進行修改... – Didifr

    1

    你的問題很混亂,缺乏多個細節。雖然你的解釋是充足的,並有幾個例子,你從來沒有說過什麼是你想要的輸出。你已經顯示了幾個輸出的外觀,但是你沒有說如果其中一個是正確的,如果不是,每種情況都有什麼問題。這樣,你的幾個代碼示例實際上是沒用的......另外,你的問題是而不是與「批處理文件中的」echo「的行爲有關」。

    爲此,我只是這裏示出的一般方法的一例從一個輸入文件當元件由空間和/或逗號(分離像數據中的例如讀一個兩維矩陣),並且輸出這樣的矩陣輸出文件:

    @ECHO off 
    SETLOCAL EnableDelayedExpansion 
    
    set "_fileIn=input.txt" 
    set "_fileOut=output.txt" 
    
    rem Read the matrice line by line from the input file 
    SET /A _ligne=0 
    for /F "usebackq delims=" %%a in ("%_fileIn%") do (
    
        rem Separate all fields in this line and store they in the next matrice row 
        set /A _ligne+=1, _colonne=0 
        for %%b in (%%a) do (
         set /A _colonne+=1 
         set _matrice[!_ligne!][!_colonne!]=%%b 
        ) 
    
    ) 
    
    rem Write all matrice lines to the output file 
    (for /L %%G in (1,1,%_ligne%) do (
    
        rem Initialize the next output line 
        set "_var=" 
    
        rem Join to it all elements in this matrice row 
        for /L %%H in (1,1,%_colonne%) do set "_var=!_var! , !_matrice[%%G][%%H]!" 
    
        rem Show the line 
        echo !_var! 
    
    )) > "%_fileOut%" 
    

    請,做回覆此代碼「沒有解決你們的問題」。如果我不知道問題是什麼,那麼我無法解決問題。

    如果你分析一下這個程序的輸出,並確定有什麼區別與所需的輸出,也許我們可以修改代碼...