0

I want to merge two .txt files following a pattern that uses one line from file1, adds a break and follows with another from file2, then repeat.

I've tried to solve this in notepad++' replace function, but it seems out of its scope completely. I've had mixed success using batch (only useful tool I'm familiar with) managing to make the .bat file past the lines separately with linebreaks, but I can't find information on how to select one line from each file alternating instead of the whole file at once.

This is the .bat file I have so far:

@Echo off
( for /f "delims=" %%A in (
    'Type 1.txt^&Echo:^&Type 2.txt'
  ) Do @Echo:%%A
) > 3.txt

Current output format:

entire file1.txt
entire file2.txt

Intended output format:

single line from file1.txt
single line from file2.txt
repeat

I continue researching but I'm not seeing much that can point me in the right direction, all help appreciated.

adr
  • 3
  • 1

2 Answers2

0

Windows command processor cmd.exe interpreting and executing a batch file is not designed for text file processing. It is designed for execution of commands and executables. There are lots of other scripting languages which would be better for this task than cmd.exe.

However, this small batch file works for this task with some limitations.

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "LineNumber=0"
for /F usebackq^ delims^=^ eol^= %%I in ("file1.txt") do (
    set /A LineNumber+=1
    set "Line[!LineNumber!]=%%I"
)

set "LineNumber=0"
(for /F usebackq^ delims^=^ eol^= %%I in ("file2.txt") do (
    set /A LineNumber+=1
    call echo(%%Line[!LineNumber!]%%
    echo(%%I
))>"file3.txt"

endlocal

The limitations are:

  • The number of non-empty lines must be equal in both input files.
  • The two input files do not contain empty lines which should be also written into output file as empty lines are ignored by FOR.
  • The lines in both input files do not contain exclamation marks as otherwise those lines are corrupted by enabled delayed expansion on double parsing of the command lines with %%I.
  • The first input file is not too large to be loaded into memory space for environment variables.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • echo /?
  • endlocal /?
  • for /?
  • set /?
  • setlocal /?
Mofi
  • 46,139
  • 17
  • 80
  • 143
0

This will do it if the files aren't the same size. The batch file counts the lines in each file and compares the line counts. If one file has more lines than the other, the shorter one will output empty lines for missing lines in file with less lines.

Personally I would go this route then just fix the blank lines with PowerShell if I needed this script for myself.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "\\server\folder"

set "InputFile1=File1.txt"
set "InputFile2=File2.txt"
set "OutputFile=mix.txt"
(set Newline=^
%==%
)

if not exist "%InputFile1%" goto EndBatch
if not exist "%InputFile2%" goto EndBatch
del "%OutputFile%" 2>nul

for /F "delims=:" %%I in ('%SystemRoot%\System32\findstr.exe /R /N "^" "%InputFile1%"') do set "LineCount1=%%I"
for /F "delims=:" %%I in ('%SystemRoot%\System32\findstr.exe /R /N "^" "%InputFile2%"') do set "LineCount2=%%I"

rem Exchange input file 1 and 2 if input file 2 has more lines than input file 1.
if %LineCount2% GTR %LineCount1% set "InputFile1=%InputFile2%" & set "InputFile2=%InputFile1%"

(
    for /F usebackq^ delims^=^ eol^= %%I in ("%InputFile1%") do (
        set "LineFile1=%%I"
        setlocal EnableDelayedExpansion
        set /P LineFile2=
        echo(!LineFile1!!Newline!!LineFile2!>>"%OutputFile%"
        endlocal
    )
)<"%InputFile2%"

:EndBatch
popd
endlocal
pause

Lines starting with a semicolon and containing an exclamation mark are also processed well by this script. Just empty lines in the two input files are ignored and cause unexpected content in output file.

[Mofi] made some edits to this version.

If you wanted to blank the lines with PowerShell like I suggested then save this as clearlines.ps1 and then run it from your batch file at the end.

$pathToFile = "\\server\folder"
(Get-Content -Path $pathToFile) -notmatch '(^[\s,-]*$)| (rows\s*affected)' | Set-Content -Path $pathToFile
shadow2020
  • 1,315
  • 1
  • 8
  • 30