2017-07-14 30 views
1

對不起,但我不擅長Windows批處理。如何合併數據文件與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批處理,我不能imagenate我怎麼有去做。

請給予你的青睞。

+2

你需要做一些研究,並嘗試在你自己的。否則,這個問題似乎是一個代碼/腳本請求,這在這裏顯然是題外話題。請閱讀[旅遊]並學習[問]! – aschipfl

+0

「File_A.txt」是否總是包含所有可能的「時間」值? – aschipfl

+0

對不起,先生。我也不喜歡問一些沒有搜索自己的東西, 實際上,我已經搜索了幾個小時,但我找不到適合我的答案,或者做了太長的代碼。 是的,File_A.txt包含時間的所有值。 – Hong

回答

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 
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