2017-06-21 61 views
0

我希望使用批處理腳本將目錄中的所有CSV/TXT文件合併在一起,並希望你們能夠幫助 - 對於腳本編程來說很新穎,所以請原諒我,如果我要求解釋每條線都做什麼, 但是我確實發現了一些有用的東西,但是在測試時它仍然保持一個標題行。我希望它會合並所有文件 - 沒有標題。使用批處理合並不帶任何頭文件的CSV文件

供參考:

@echo off 
setlocal enableextensions disabledelayedexpansion 

rem configure paths 
set "source=C:\Users\Khalid\Desktop\New_folder\p*.csv" 
set "target=C:\Users\Khalid\Desktop\newfile.csv" 

rem remove output file if needed 
if exist "%target%" del "%target%" >nul 2>nul 

rem search for header row 
set "headerRow=" 
for %%f in ("%source%") do (
    <"%%~ff" (for /l %%a in (1 1 10) do if not defined headerRow set /p 
     "headerRow=") 
     if defined headerRow goto haveHeader 
    ) 
    :haveHeader 
    if not defined headerRow (
     echo ERROR: impossible to get header row. 
     goto endProcess 
) 

rem output header to header file to use as filter. 
rem header is cut to avoid findstr limitations on search strings 
set "headerFile=%temp%\%~nx0_headerFile.tmp" 
setlocal enableextensions enabledelayedexpansion 
> "%headerFile%" echo(!headerRow:~0,125! 
endlocal 


rem search for input files with matching headers to join to final file 
for /f "tokens=*" %%f in ('findstr /m /b /l /g:"%headerFile%" "%source%"') do (
    if not exist "%target%" (

      rem first file is directly copied 
      copy "%%~f" "%target%" /y > nul 2>nul 

     ) else (

      rem next files are filtered to exclude the header row 
      findstr /v /b /l /g:"%headerFile%" "%%~f" >> "%target%" 
    ) 
    echo ... [%%~ff] joined to %target% 
) 

rem remove the temporary header file 
del "%headerFile%" >nul 2>nul 

:endProcess 
    endlocal 

回答

0

一個簡單的方法可能是

@echo off 
    setlocal enableextensions disabledelayedexpansion 

    rem configure paths 
    set "source=p*.csv" 
    set "target=newfile.csv" 

    >"%target%" (
     for %%a in ("%source%") do (
      set "headerRow=" 
      <"%%~fa" (
       for /l %%h in (1 1 10) do if not defined headerRow set /p "headerRow=" 
       findstr "^" 
      ) 
     ) 
    ) 

對於每個輸入文件,讀取它的頭和轉儲文件的其餘部分。所有的輸出都被髮送到輸出文件。

注意,這種方法有一個限制:set /p無法讀取超過1021個字符,如果你的.csv文件有更長的線,然後,按照原來的做法,你可以使用像

@echo off 
    setlocal enableextensions disabledelayedexpansion 

    rem configure paths 
    set "source=p*.csv" 
    set "target=newfile.csv" 
    set "headerFile=%temp%\%~nx0_headerFile.tmp" 

    >"%target%" (
     for %%a in ("%source%") do (
      set "headerRow=" 
      <"%%~fa" (
       for /l %%h in (1 1 10) do if not defined headerRow set /p "headerRow=" 
       setlocal enableextensions enabledelayedexpansion 
       > "%headerFile%" echo(!headerRow:~0,125! 
       endlocal 
      ) 
      findstr /v /b /l /g:"%headerFile%" "%%~fa" 
     ) 
    ) 

    rem remove the temporary header file 
    del "%headerFile%" >nul 2>nul 
+0

第二個工作對我來說更好,因爲腳本將需要閱讀超過1021個字符的文件。不過你說這是set/p的限制,爲什麼它還用在第二個腳本中?也感謝你的這個解決方案,並感謝你的其他人的輸入,非常感謝 –

+0

@KhalidSheikh,限制不涉及文件大小,但行長。在第二個示例中,它用於至少檢索標題行的開頭,稍後將用作行匹配的非匹配開始行來放棄整行。 –

+0

非常感謝您對整個答案的解釋 –

0

如果文件對每個文件的一行一行標題,行順序並不重要:

@Echo Off 
(For %%A In ("%UserProfile%\Desktop\New_folder\p*.csv") Do More +1 "%%a")>"%UserProfile%\Desktop\newfile.csv" 
+1

這種方法有兩個可能的問題:1)'more'命令將空格替換爲製表符。 2)對於超過65535行的文件,它要求用戶按一個鍵繼續。 –

+0

同意,但是我認爲合併文件中的一個或多個具有超過65535行的文件是可恥的,而且OP已經提供了很少的信息來作出更好的判斷。 – Compo

+0

/謝謝大家,我不認爲我會合並的任何文件將有更多的3萬行,但如果我誠實但是。讓我們只是說,我有一個67k線的文件將由MC ND提到的上述方法工作?也只是很好奇,爲什麼限制65535線呢? –