如何合并数据文件并匹配Windows批处理中的数据

时间:2017-07-14 06:25:23

标签: batch-file merge

我很抱歉,但我不擅长Windows批处理。

我想合并两个或多个按键值匹配的文件。这些文件的行数不同。

例如:

File_A.txt

Time, D1, D2
1.1, 11, 12
1.2, 21, 22
1.3, 31, 32
1.4, 41, 42
1.5, 51, 52

File_B.txt

Time, D3, D4
1.1, 13, 14
1.3, 33, 34
1.4, 43, 44

File_C.txt

Time, D5, D6
1.2, 25, 26
1.4, 45, 46
1.5, 55, 56

我想得到:

Merged.txt

Time, D1, D2, D3, D4, D5, D6
1.1, 11, 12, 13, 14
1.2, 21, 22,   ,   , 25, 26
1.3, 31, 32, 33, 34
1.4, 41, 42, 43, 44, 45, 46
1.5, 51, 52,   ,   , 55, 56

如果我用C / C ++制作,那么它会很容易,但由于我的情况,我必须在Windows批处理中制作它,而且我无法想象我必须做什么。

请帮忙。

2 个答案:

答案 0 :(得分:1)

此解决方案在当前目录中处理名为File_*.txt的所有文件,并假设“主文件”(包含所有密钥的文件)是第一个文件

@echo off
setlocal EnableDelayedExpansion

set "keys="
for %%f in (File_*.txt) do (
   if not defined keys (
      for /F "usebackq tokens=1* delims=," %%a in ("%%f") do (
         set "line[%%a]=%%a,%%b"
         set "keys=!keys! %%a"
      )
   ) else (
      set "rest=!keys!"
      for /F "usebackq tokens=1* delims=," %%a in ("%%f") do (
         set "line[%%a]=!line[%%a]!,%%b"
         set "rest=!rest: %%a=!"
      )
      for %%k in (!rest!) do set "line[%%k]=!line[%%k]!,   ,   "
   )
)
(for %%k in (%keys%) do echo !line[%%k]!) > Merged.txt

使用三个示例文件作为输入,这是输出:

Time, D1, D2, D3, D4, D5, D6
1.1, 11, 12, 13, 14,   ,
1.2, 21, 22,   ,   , 25, 26
1.3, 31, 32, 33, 34,   ,
1.4, 41, 42, 43, 44, 45, 46
1.5, 51, 52,   ,   , 55, 56

答案 1 :(得分:0)

这是一个应该执行您想要的批处理脚本,尽管它对大文件效率不高。它依赖于以下事实:所有文件都具有相同数量的列(在我们的情况下为三个),并且提供的第一个文件在其第一列中具有所有可能的值。假设脚本保存为merge.bat,您需要提供要合并为命令行参数的文件,例如:

merge.bat "File_A.txt" "File_B.txt" "File_C.txt"

结果文件在当前工作目录中始终为Merged.txt。所以这是代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SEPAR=, "
set "_FILL=%_SEPAR%  %_SEPAR%  "
set "_RESULT=Merged.txt"

set "FIRST=#"
for %%A in (%*) do (
    if defined FIRST (
        > nul copy /Y "%%~nxA" "%_RESULT%"
        set "FIRST="
    ) else (
        > "%_RESULT%.tmp" (
            for /F usebackq^ delims^=^ eol^= %%F in ("%_RESULT%") do (
                set "FLAG=" & set "LINE=%%F"
                for /F usebackq^ delims^=^ eol^= %%I in ("%%~A") do (
                    for /F "eol=%_SEPAR:~,1% delims=%_SEPAR%" %%E in ("%%F") do (
                        for /F "tokens=1* eol=%_SEPAR:~,1% delims=%_SEPAR%" %%J in ("%%I") do (
                            if "%%E"=="%%J" set "STR=%%K" & set "FLAG=#"
                        )
                    )
                )
                setlocal EnableDelayedExpansion
                if defined FLAG (
                    echo(!LINE!%_SEPAR%!STR!
                ) else (
                    echo(!LINE!%_FILL%
                )
                endlocal
            )
        )
        > nul move /Y "%_RESULT%.tmp" "%_RESULT%"
    )
)

endlocal
exit /B

将您的示例文件作为输入,Merged.txt中的输出将是:

Time, D1, D2, D3, D4, D5, D6
1.1, 11, 12, 13, 14,   ,   
1.2, 21, 22,   ,   , 25, 26
1.3, 31, 32, 33, 34,   ,   
1.4, 41, 42, 43, 44, 45, 46
1.5, 51, 52,   ,   , 55, 56

这是一个替代批处理脚本。与另一个文档相比,第一个文件不再需要包含其第一列中的所有可能值。这是代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SEPAR=, "
set "_FILL=%_SEPAR%  %_SEPAR%  "
set "_RESULT=Merged.txt"

for /F "delims==" %%E in ('set "$" 2^> nul') do set "%%E="
set /A "INDEX=0"
for %%A in (%*) do (
    for /F "usebackq eol=%_SEPAR:~,1% delims=%_SEPAR%" %%E in ("%%~A") do (
        call set "NUMBER=000000000000%%INDEX%%"
        if not defined $[%%E] call set "$[%%E]=%%NUMBER:~-12%%%_SEPAR%%%E"
        set /A "INDEX+=1"
    )
)
> "%_RESULT%.tmp" (
    for /F "tokens=1* delims==" %%E in ('set "$"') do @(
        echo(%%F
    )
)
> "%_RESULT%" (
    for /F "tokens=1* delims=%_SEPAR%" %%E in ('sort "%_RESULT%.tmp"') do @(
        echo(%%F
    )
)
del "%_RESULT%.tmp"
for %%A in (%*) do (
    > "%_RESULT%.tmp" (
        for /F usebackq^ delims^=^ eol^= %%F in ("%_RESULT%") do (
            set "FLAG=" & set "LINE=%%F"
            for /F usebackq^ delims^=^ eol^= %%I in ("%%~A") do (
                for /F "eol=%_SEPAR:~,1% delims=%_SEPAR%" %%E in ("%%F") do (
                    for /F "tokens=1* eol=%_SEPAR:~,1% delims=%_SEPAR%" %%J in ("%%I") do (
                        if "%%E"=="%%J" set "STR=%%K" & set "FLAG=#"
                    )
                )
            )
            setlocal EnableDelayedExpansion
            if defined FLAG (
                echo(!LINE!%_SEPAR%!STR!
            ) else (
                echo(!LINE!%_FILL%
            )
            endlocal
        )
    )
    > nul move /Y "%_RESULT%.tmp" "%_RESULT%"
)

endlocal
exit /B