2016-03-08 37 views
0

我想製作一個通用的批處理腳本,它將讀取將包含固定寬度平面文件源的各種寬度/列長度的模式文件,並最終根據列長度創建目標csv文件。通用文本轉換器

實施例:

Schema.txt

COL1,5 
COL2,2 
COL3,4 
COL4,3 
COL5,6 

所以上面schema.txt文件包含列list.It還包含每個字段的寬度。我們的來源將始終是固定寬度的平面文件。我們的目標是將其轉換爲csv。

Source1.txt

11111223333444555555 
11111223333444555555 

Target1.txt

11111,22,3333,444,555555 
11111,22,3333,444,555555 

Source2.txt

11111 333344466666 
11111223333 66666 

Target2.txt

11111,,3333,444,66666 
11111,22,333,,66666 

,所以它應該能夠處理空間和空白,就像我們在第二個源文件中看到的那樣。 模式應該是一個動態文件,如果我們提供結構,bat文件將創建一個與來自源的結構完全相同的csv。最終目標文件應該具有從模式文件中獲取的頭文件。 請幫忙。下面

我的本次代碼給出:

echo off 
setlocal EnableDelayedExpansion 
echo a,b,c final.txt 
rem replace the €€€ string with any unused one 
set "fooString=€€€" 
for /f "tokens=1 delims=;" %%i in (source.txt) do (
    set "x=%%i" 
    for /f "tokens=1,2 delims=," %%a in (config.txt) do (
    call SET "VARraw=!x:~%%a,%%b!%fooString%" 
    rem replaced with respect to the OP's comment: for %%p in (!VARraw!) do (
    for /F "tokens=*" %%p in ("!VARraw!") do (
     set "rav=%%p" 
     set "var=!rav:%fooString%=!" 
     echo/|set /p "=!var!," 
    )   final.txt 
) 
) 

目前的config.txt包含

0,9 
9,3 
12,11 
23,7 
30,1 

但我想修改it.Want只保留字段名稱和寬度。不是起始位置和寬度。

現有代碼的問題是,它將結果打印在一行中,但是我想在每行結束後打開\ n。

+3

到目前爲止您嘗試過什麼?請分享您的代碼!我們不會爲你做你的工作,我們在這裏幫助你解決你遇到的特定編程問題;看看也[這裏](http://stackoverflow.com/help/how-to-ask)... – aschipfl

+0

@aschipfl我喜歡這是如何開始與「我想要」,然後只是告訴他想要什麼我們做。 –

+1

@ DennisvanGils:_「我希望你爲我製作一個通用的批處理腳本......」是的,我認爲這將是對這個問題的更現實的描述。 **';-)'** – Aacini

回答

0
@echo off 
setlocal EnableDelayedExpansion 

rem Load the schema 
set /A numCol=0, maxSpc=0 
set "header=" 
set "spaces=" 
for /F "tokens=1,2 delims=," %%a in (Schema.txt) do (
    set /A numCol+=1 
    set "header=!header!,%%a" 
    set "col[!numCol!]=%%b" 
    if %%b gtr !maxSpc! (
     set /A spc=%%b-maxSpc, maxSpc=%%b 
     for /L %%i in (1,1,!spc!) do set "spaces=!spaces! " 
    ) 
) 

rem Process the input file 
echo %header:~1% 
for /F "delims=" %%a in (%1) do (
    set "in=%%a" 
    set "start=0" 
    set "out=" 
    for /L %%i in (1,1,%numCol%) do for /F "tokens=1,2" %%j in ("!start! !col[%%i]!") do (
     set "col=!in:~%%j,%%k!" 
     if "!col!" equ "!spaces:~0,%%k!" set "col=" 
     set "out=!out!,!col!" 
     set /A start+=%%k 
    ) 
    echo !out:~1! 
) 

輸出例如會話:

C:\> type Schema.txt 
COL1,5 
COL2,2 
COL3,4 
COL4,3 
COL5,6 

C:\> type Source1.txt 
11111223333444555555 
11111223333444555555 

C:\> test Source1.txt 
COL1,COL2,COL3,COL4,COL5 
11111,22,3333,444,555555 
11111,22,3333,444,555555 

C:\> type Source2.txt 
11111 333344466666 
11111223333 66666 

C:\> test Source2.txt 
COL1,COL2,COL3,COL4,COL5 
11111,,3333,444,66666 
11111,22,3333,,66666 
+0

發生了什麼事?這個解決方案有用嗎? – Aacini

+0

你的解決方案是完美的。我永遠不可能寫出這樣一個成熟的代碼,至少不能用我在dos中掌握的當前腳本知識。我只想提出兩件事:1.如果我將這段代碼用於大約10萬條記錄的大文件,則構建最終輸出需要很長時間。這是dos的限制嗎? 2.如果可能的話,請通過你的代碼走一點,因爲我想學習..不要盲目複製粘貼...再次感謝幫助我。 – Sumit

+0

@Aschipfl ...你的代碼也很有魅力。當我嘗試處理10萬條記錄時需要一點時間。它與DOS的侷限性有關係嗎?如果可能的話,請你帶着我的代碼走過去,因爲我想學習的不僅僅是複製粘貼。再次感謝幫助我。 – Sumit

0

下面的腳本(我們稱之爲convert.bat)將根據您的要求通過命令行參數提供到CSV文件中的文本文件。您可以提供結果文件作爲第二個參數;如果省略,則輸出顯示在控制檯上。默認模式文件Schema.txt可如果指定了第三個參數進行更改:(所以使用像:convert.bat source.txt [target.txt [schema.txt]]

@echo off 
setlocal EnableExtensions EnableDelayedExpansion 

rem Remove leading blanks of every field if this value is non-empty 
rem (inconvenient side effect: exclamation marks `!` get lost): 
set "DELBLANKS=REMOVE" 

rem Specify source file as first command line argument: 
set "SOURCE=%~1" 
rem Specify target file as second argument (optionally): 
set "TARGET=%~2" 
rem Provide scheme file as third argument (default is "Schema.txt"): 
set "SCHEME=%~3" 

rem Check the given command line arguments: 
if not defined SOURCE >&2 echo ERROR: no source file given^^! & exit /B 1 
if not defined TARGET set "TARGET=con" 
if not defined SCHEME set "SCHEME=%~dp0Schema.txt" 

rem Read scheme file and build header: 
set "HEADER=" 
set /A POSITION=0 
set /A COLUMN=0 
for /F "usebackq tokens=1,2 delims=," %%I in ("%SCHEME%") do (
    set /A COLUMN+=1 
    set "HEADER=!HEADER!,%%I" 
    if not "%%J"=="" (
     set "WIDTH=%%J" 
     set /A WIDTH[!COLUMN!]+=!WIDTH!+0 
     set /A POSITION[!COLUMN!]=!POSITION! 
     set /A POSITION+=!WIDTH!+0 
    ) 
) 

rem Convert source file into CSV format and store to target file: 
> "!TARGET!" (
    echo(!HEADER:~1! 
    for /F usebackq^ delims^=^ eol^= %%L in ("!SOURCE!") do (
     setlocal DisableDelayedExpansion 
     set "LINE=%%L" 
     setlocal EnableDelayedExpansion 
     set "LINE=!LINE:,=;!" 
     set "CSV=" 
     set /A POSITION=0 
     set /A COLUMN=0 
     for /L %%C in (1,1,%COLUMN%) do (
      for /F "tokens=1,2 delims=," %%P in ("!POSITION[%%C]!,!WIDTH[%%C]!") do (
       if defined DELBLANKS (
        for /F tokens^=*^ eol^= %%S in ("!LINE:~%%P,%%Q!,") do (
         set "CSV=!CSV!%%S" 
        ) 
       ) else (
        set "CSV=!CSV!!LINE:~%%P,%%Q!," 
       ) 
      ) 
     ) 
     if defined CSV echo(!CSV:~,-1! 
     endlocal 
     endlocal 
    ) 
) 

endlocal 
exit /B 

架構中的文件的源文件,也是頭不應包含任何驚歎號!。 源文件中的任何逗號,將被分號;替代。