2016-03-08 71 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 

架构中的文件的源文件,也是头不应包含任何惊叹号!。 源文件中的任何逗号,将被分号;替代。