循环遍历子目录中的文件夹并组合文本文件

时间:2017-07-13 13:08:19

标签: windows powershell batch-file

我想循环遍历子目录中的文件夹,并将所有文本文件合并到一个文件中。我在网上找到了一些答案,但似乎都没有。任何帮助深表感谢。我提供了我在下面找到的内容。在下面的示例中,DummyFolder有多个包含.txt files的子目录,需要合并到1个文件中。我昨天得到了代码3,但不知怎的,我改变了一些东西而且由于某种原因它不再起作用了。

代码1:

@echo off
set "header=C:\Users\user\Desktop\DummyFolder\Headings.txt"
set "folder=C:\Users\user\Desktop\DummyFolder\"
set "tempFile=%folder%\temp.txt"
for %%F in ("%folder%\*.txt") do (
   type "%header%" >"%tempFile%"
   type "%%F" >>"%tempFile%"
   move /y "%tempFile%" "%%F" >nul
)

还找到了这段代码(代码2):

$startingDir = 'C:\Users\user\Desktop\DummyFolder\'
$combinedDir = 'C:\Users\user\Desktop\DummyFolder\CombinedTextFiles'

Get-ChildItem $startingDir -Recurse | Where-Object {
   $txtfiles = Join-Path $_.FullName '*.txt'
   $_.PSIsContainer -and (Test-Path $txtfiles)
} | ForEach-Object {
   $merged = Join-Path $combinedDir ($_.Name + '_Merged.txt')
   Get-Content $txtfiles | Set-Content $merged
}

还找到了这段代码(代码3):

@echo on
set folder="C:\Users\user\Desktop\DummyFolder\"
for /F %%a in ('dir /b /s %folder%') do (
   if "%%~xa" == ".txt" (
      (echo/------------------------------
      type %%~a
      echo/)>>"%~dp0list.txt"
   )
)

5 个答案:

答案 0 :(得分:0)

在CMD中,您可以这样做:

@echo off

set "basedir=C:\some\folder"
set "outfile=C:\path\to\output.txt"

(for /r "%basedir%" %f in (*.txt) do type "%~ff") > "%outfile%"

要在批处理文件中使用,您需要将%f更改为%%f,将%~ff更改为%%~ff

在PowerShell中,您可以执行以下操作:

$basedir = 'C:\some\folder'
$outfile = 'C:\path\to\output.txt'

Get-ChildItem $basedir -Include *.txt -Recurse | Get-Content |
    Set-Content $outfile

答案 1 :(得分:0)

代码3并不错,但它不适用于路径中的空格,因为您使用的是标准delims,因为您没有提供空格。还有一些关于在路径中使用空格的其他错误。

以下代码适用于所有子目录中的所有txt files并将其组合在一起。它将在此批处理文件所在的文件夹中创建一个新文件list.txt。如果已存在list.txt,则会覆盖该@echo off set "folder=C:\Users\user\Desktop\DummyFolder\" rem create new empty file: list.txt in directory of batch file: %~dp0 break>"%~dp0list.txt" rem loop through all output lines of the dir command, unset delimns rem so that space will not separate for /F "delims=" %%a in ('dir /b /s "%folder%"') do ( rem just look for txt files if "%%~xa" == ".txt" ( rem don't use the list.txt if not "%%a" == "%~dp0list.txt" ( rem append the output of the whole block into the file (echo/------------------------------ type "%%a" echo/)>>"%~dp0list.txt" ) ) ) 。请注意,它是批处理文件:

echo This is a message visible on the command prompt

如果您不了解某些内容,那么在互联网上找到好东西很容易,因为有几个很棒的批处理脚本网站。此外,您始终可以使用rem This is a comment来展示可能有用的内容,例如因此你可以“调试”并看看会发生什么。 代码中的注释(break)之外的一些解释:

<强> 1。 set varname=Content命令:

要清除文件,我使用break命令,根本不会产生任何输出。我将重定向到文件的空输出,请在此处阅读:https://stackoverflow.com/a/19633987/8051589

<强> 2。 一般变量:

您可以通过set "varname=Content"设置变量我更喜欢使用引号:%,因为它也适用于重定向字符。将变量与一个开头%和一个尾随echo %varname%一起使用,例如>。你可以在https://ss64.com/nt/set.html上阅读很多内容。我认为ss64可能是批处理脚本的最佳站点。

第3。 重定向>>>

您可以使用>>>重定向命令的输出,其中>>创建新文件并覆盖现有文件,for /f附加到文件或创建一个文件如果不存在。还有很多事情可能:https://ss64.com/nt/syntax-redirection.html

<强> 4。 for /f循环:

在批处理文件中,使用%循环遍历命令输出行。使用的变量将在其前面加上2 %%adelimns。我还将分隔符for /f设置为空,这样命令输出就不会被分成几个标记。
您可以在https://ss64.com/nt/for_cmd.html上阅读有关%%~xa循环的大量详细信息。

<强> 5。 特殊变量语法%~dp0%%a

保存dir命令的一行的变量%%~xa只能通过:%~dp0扩展到文件扩展名,如下所述:https://stackoverflow.com/a/5034119/8051589( ... )>>变量包含批处理文件所在的路径,请参见此处:https://stackoverflow.com/a/10290765/8051589

<强> 6。 阻止重定向(

要一次重定向多个命令,您可以打开一个块),执行命令,关闭块 2017-07-13 06:30:20,607] Artifact hoprepositoryweb:war exploded: Artifact is being deployed, please wait... 13-Jul-2017 18:30:23.223 INFO [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 151 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started 157 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Thu Jul 13 18:30:23 PKT 2017]; root of context hierarchy 276 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Registering annotated classes: [class com.hop.config.Application] 1757 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Building JPA container EntityManagerFactory for persistence unit 'hoporbitsapp' 13-Jul-2017 18:30:25.098 INFO [RMI TCP Connection(3)-127.0.0.1] org.hibernate.jpa.internal.util.LogHelper.logPersistenceUnitInformation HHH000204: Processing PersistenceUnitInfo [ name: hoporbitsapp ...] 13-Jul-2017 18:30:25.273 INFO [RMI TCP Connection(3)-127.0.0.1] org.hibernate.Version.logVersion HHH000412: Hibernate Core {5.2.10.Final} 13-Jul-2017 18:30:25.279 INFO [RMI TCP Connection(3)-127.0.0.1] org.hibernate.cfg.Environment.<clinit> HHH000206: hibernate.properties not found 13-Jul-2017 18:30:25.392 INFO [RMI TCP Connection(3)-127.0.0.1] org.hibernate.annotations.common.reflection.java.JavaReflectionManager.<clinit> HCANN000001: Hibernate Commons Annotations {5.0.1.Final} 13-Jul-2017 18:30:29.163 INFO [RMI TCP Connection(3)-127.0.0.1] org.hibernate.dialect.Dialect.<init> HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect 13-Jul-2017 18:30:29.242 INFO [RMI TCP Connection(3)-127.0.0.1] org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl.useContextualLobCreation HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4 6822 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'hoporbitsapp' 13-Jul-2017 18:30:30.298 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [C:\pers\Talha docs\work\Tomcat2\apache-tomcat-8.5.16\webapps\manager] 13-Jul-2017 18:30:30.379 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [C:\pers\Talha docs\work\Tomcat2\apache-tomcat-8.5.16\webapps\manager] has finished in [80] ms 7679 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/]}" onto public java.lang.String com.hop.controller.IndexController.index() 7684 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/user],methods=[POST]}" onto public java.lang.String com.hop.controller.UserController.register(com.hop.model.UserModel) 8154 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Thu Jul 13 18:30:23 PKT 2017]; root of context hierarchy 8499 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 8348 ms 13-Jul-2017 18:30:31.819 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal One or more Filters failed to start. Full details will be found in the appropriate container log file 13-Jul-2017 18:30:31.821 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors 8516 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Closing Root WebApplicationContext: startup date [Thu Jul 13 18:30:23 PKT 2017]; root of context hierarchy 13-Jul-2017 18:30:31.886 WARNING [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [ROOT] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. [2017-07-13 06:30:31,909] Artifact hoprepositoryweb:war exploded: Error during artifact deployment. See server log for details. 并使用重定向。您也可以执行每个命令并重定向只有具有相同效果的命令。

答案 2 :(得分:0)

有很多方法可以做到这一点。例如,使用Wolfram Language即可:

StringJoin @@ 
    FileSystemMap[
        If[FileExtension[#] == "txt", Import[#, "Text"]] &, 
        "C:\\Users\\user\\Desktop\\DummyFolder\\", Infinity, 1]

然后使用

编写结果
Export[C:\\Users\\user\\Desktop\\, %, "Text"]

您也可以使用Python,Perl等执行此操作。仅在您需要共享解决方案并希望避免安装程序时才使用PowerShell。我不会花太多时间学习1981年技术(CMD)。

答案 3 :(得分:0)

对于您正在寻找的内容,这可能是一个简单的答案,usebackq对于允许“”绕路径很重要。 tokens = *包含所有信息。要在控制台中使用而不是批处理文件,请将%%更改为%。

    for /f "tokens=*" %%a in ('dir /s /b C:\testpath\*.txt') do (for /f "usebackq tokens=*"  %%b in ("%%a") do (echo %%b >> C:\test.txt))

答案 4 :(得分:0)

假设您的源文件位于根目录DummyFolder的直接子目录中,并且您希望Headings.txt的内容仅在结果文件的顶部发生一次,您可以完成您的任务使用以下脚本:

@echo off

rem // Define constants here:
set "folder=C:\Users\user\Desktop\DummyFolder"
set "header=%folder%\Headings.txt"
set "result=%folder%\merged.txt"

rem // Prepare result file, copy content of header file:
copy "%header%" "%result%" > nul
rem // Enumerate immediate sub-directories of the given root directory:
for /D %%D in ("%folder%\*") do (
    rem // Enumerate matching files per sub-directory:
    for %%F in ("%%~D\*.txt") do (
        rem // Append content of current file to result file:
        copy /Y "%result%" + "%%~F" "%result%" /B > nul
    )
)

如果您的源文件位于目录树DummyFolder中的任何位置,则需要确保未迭代头文件Headings.txt和结果文件merged.txt

@echo off

rem // Define constants here:
set "folder=C:\Users\user\Desktop\DummyFolder"
set "header=Headings.txt"
set "result=merged.txt"

rem // Prepare result file, copy content of header file:
copy "%folder%\%header%" "%folder%\%result%" > nul
rem // Enumerate matching files in the whole given directory tree:
for /R "%folder%" %%F in ("*.txt") do (
    rem // Exclude the header file to be re-processed:
    if /I not "%%~nxF"=="%header%" (
        rem // Exclude the result file to be processed:
        if /I not "%%~nxF"=="%result%" (
            rem // Append content of current file to result file:
            copy /Y "%folder%\%result%" + "%%~F" "%folder%\%result%" /B > nul
        )
    )
)