Contents of file A1
:
AA
VV
BB
Contents of file A2
:
DD
EE
FF
I want to merge the
We can load the contents of the files into Batch variable arrays so each of its lines can be directly accessed in any way you wish:
@echo off
setlocal EnableDelayedExpansion
rem Load first file into A1 array:
set i=0
for /F "delims=" %%a in (A1.txt) do (
set /A i+=1
set A1[!i!]=%%a
)
rem Load second file into A2 array:
set i=0
for /F "delims=" %%a in (A2.txt) do (
set /A i+=1
set A2[!i!]=%%a
)
rem At this point, the number of lines is in %i% variable
rem Merge data from both files and create the third one:
for /L %%i in (1,1,%i%) do echo !A1[%%i]! is from !A2[%%i]!>> A3.txt
EDIT Alternative solution
There is another way to do it that don't use Batch variables so it can be used on files of any size, although it is slower. I borrowed the method used by Andy Morris in its solution: 1- Insert line numbers in both files, 2- Combine both files in one, 3- Sort the combined file, and 4- Merge groups of lines into one same line. The program below is basically Andy's one with several small modifications that made it faster (with a subtle error fixed).
@echo off
setlocal EnableDelayedExpansion
call :AddLineNumbers A1.txt A > Both.txt
call :AddLineNumbers A2.txt B >> Both.txt
sort Both.txt /O Sorted.txt
echo EOF: >> Sorted.txt
call :creatNewLines < Sorted.txt > Result.txt
goto :eof
:AddLineNumbers
findstr /n ^^ %1 > tem.tmp
for /f "tokens=1* delims=:" %%a in (tem.tmp) do (
set /a lineNo=1000000+%%a
echo !lineNo!%2:%%b
)
goto :eof
:creatNewLines
set /p lineA1=
for /f "tokens=1* delims=:" %%a in ("%lineA1%") do (
if %%a == EOF goto :eof
set /p dummy=%%b< nul
)
set /p lineA2=
for /f "tokens=1* delims=:" %%a in ("%lineA2%") do echo is from %%b
goto creatNewLines
SORT command order lines based on its contents. Andy's original method may fail because after the line number the lines are ordered based on line contents, so the lines of each file may be misplaced. In this method an additional character (A or B) is added after the line number, so the lines of each file are always placed in the right place.
If your original data is in Data1.txt and Data2.txt this should do:
@echo off
call :AddLineNumbers data1.txt Tem1.txt
call :AddLineNumbers data2.txt Tem2.txt
copy tem1.txt + tem2.txt tem3.txt
sort < tem3.txt > tem4.txt
call :GetDataOut tem4.txt > tem5.txt
set OddData=
for /f %%a in (tem5.txt) do call :creatNewLines %%a
goto :eof
:AddLineNumbers
find /v /n "xx!!xx" < %1 > tem.txt
call :ProcessLines > %2
goto :eof
:ProcessLines
for /f "tokens=1,2 delims=[]" %%a in (tem.txt) do call :EachLine %%a %%b
goto :eof
:eachLine
set LineNo=00000%1
set data=%2
set LineNo=%LineNo:~-6%
echo %LineNo% %data%
goto :eof
:GetDataOut
for /f "tokens=2" %%a in (%1) do @echo %%a
goto :eof
:creatNewLines
if "%oddData%"=="" (
set oddData=%1
) else (
echo %oddData% %1
set oddData=
)
goto :eof
If using linux, I would recommend using cut and paste (command line). See the man pages.
Alternatively, if you don't need the automation, you could use vim block mode cut and paste. Enter block mode visual mode with control-v.