Loop through folders in subdirectories and combine text files

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

I am wanting to loop through folders within a subdirectory and combine all text files into one file. I found some answers online but none seems to work. Any help is much appreciated. I have provided what I've found below. In the example below the DummyFolder has multiple subdirectories that contain .txt files that need to be merged into 1 file. I got code 3 to work yesterday but somehow I changed something and it is no longer working for some reason.

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

Also found this code (Code 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 } 

Also found this code (Code 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"    ) ) 

回答1:

In CMD you'd do something like this:

@echo off  set "basedir=C:\some\folder" set "outfile=C:\path\to\output.txt"  (for /r "%basedir%" %f in (*.txt) do type "%~ff") > "%outfile%" 

For use in batch files you need to change %f to %%f and %~ff to %%~ff.


In PowerShell you'd do something like this:

$basedir = 'C:\some\folder' $outfile = 'C:\path\to\output.txt'  Get-ChildItem $basedir -Include *.txt -Recurse | Get-Content |     Set-Content $outfile 


回答2:

There are so many ways to do this. For example, using the Wolfram Language you can:

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

An then write the result using

Export[C:\\Users\\user\\Desktop\\, %, "Text"] 

You can also do this with Python, Perl, etc.. use PowerShell only if you need to share your solution and want to avoid installers. I would not spend too much time learning 1981 technology (CMD).



回答3:

Assuming that your source files are located in immediate sub-directories of the root directory DummyFolder and that you want the content of Headings.txt to occur once only on top of the resulting file, you could accomplish your task using the following script:

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

In case your source files are located anywhere in the directory tree DummyFolder, you need to make sure that the header file Headings.txt and the result file merged.txt are not iterated:

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


回答4:

This may be a simple answer for what you are looking for, the usebackq is important to allow "" around paths. tokens=* to include all information. To use in a console instead of a batch file change %% to %.

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


回答5:

Code 3 is not bad but it won't work with spaces in a path because you use the standard delims as you're not providing one. Also there a several other errors about working with spaces in a path.

The following code works and combine all txt files in all subdirectories. It will create a new file list.txt in the folder where this batch file is located. If there is already an existing list.txt it will be overwritten. Note that it's a batch file:

@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"       )    ) ) 

If you don't understand something it's quite easy to find something good on the internet because there are several great batch scripting sites. Further you can always use echo This is a message visible on the command prompt to display something that might be useful e.g. variables etc. With that you can "debug" and look what happens. Some explanations beyond the comments (rem This is a comment) in the code:

1. break command:

To clear a file I use the break command which will produce no output at all. That empty output I redirect to a file, read it here: https://stackoverflow.com/a/19633987/8051589.

2. General variables:

You set variables via set varname=Content I prefer the way as I do it with quotes: set "varname=Content" as it works with redirection characters also. Use the variable with one starting % and one trailing % e.g. echo %varname%. You can read a lot of it on https://ss64.com/nt/set.html. I think ss64 is probably the best site for batch scripting out there.

3. Redirection > and >>:

You can redirect the output of a command with > or >> where > creates a new file and overwrites existing files and >> appends to a file or create one if not existing. There are a lot more thing possible: https://ss64.com/nt/syntax-redirection.html.

4. for /f loop:

In a batch file you loop through the lines of a command output by using a for /f loop. The variable that is used will be written with 2 % in front of it, here %%a. I also set the delimiter delimns to nothing so that the command output will not be separated into several tokens.
You can read a lot of details about a for /f loop at: https://ss64.com/nt/for_cmd.html.

5. Special variable syntax %%~xa and %~dp0:

The variable %%a which hold one line of the dir command can be expand to the file extension only via: %%~xa as explained here: https://stackoverflow.com/a/5034119/8051589. The %~dp0 variable contains the path where the batch file is located see here: https://stackoverflow.com/a/10290765/8051589.

6. Block redirection ( ... )>>:

To redirect multiple commands at once you can open a block (, execute commands, close the block ) and use a redirection. You could also execute every command and redirect that only that would have the same effect.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!