2017-06-21 101 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线呢? –