Пакетный скрипт для слияния строк из двух файлов в третий файл - PullRequest
1 голос
/ 16 ноября 2011

Содержимое файла A1:

AA
VV
BB

Содержимое файла A2:

DD
EE
FF

Я хочу объединить содержимое A1 и A2, как показано ниже, в A3, так что ожидаемые данные в A3:

AADD
VVEE
BBFF

В качестве альтернативы ожидаемый результат в A3 может быть:

AA is from DD
VV is from EE
BB is from FF

Спасибо за помощь. Я пытался выполнить поиск до того, как отправил сообщение, и не смог найти кого-то, кто уже опубликовал нечто подобное ...

Ответы [ 3 ]

3 голосов
/ 17 ноября 2011

Мы можем загрузить содержимое файлов в переменные массивы Batch, чтобы к каждой из его строк можно было обращаться напрямую любым удобным вам способом:

@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

РЕДАКТИРОВАТЬ Альтернативное решение

Есть еще один способ сделать это, не используя переменные пакета, поэтому его можно использовать для файлов любого размера, хотя он и медленнее. Я заимствовал метод, используемый Энди Моррисом в своем решении: 1- Вставить номера строк в оба файла, 2- Объединить оба файла в один, 3- Сортировать объединенный файл и 4- Объединить группы строк в одну и ту же строку. Ниже приведена программа Энди с несколькими небольшими модификациями, которые сделали ее быстрее (с исправленной незначительной ошибкой).

@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 в зависимости от их содержимого. Оригинальный метод Энди может потерпеть неудачу, потому что после номера строки строки упорядочены на основе содержимого строки, поэтому строки каждого файла могут быть смещены. В этом методе после номера строки добавляется дополнительный символ (A или B), поэтому строки каждого файла всегда располагаются в нужном месте.

1 голос
/ 16 ноября 2011

Если ваши исходные данные находятся в Data1.txt и Data2.txt, это должно сделать:

@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
0 голосов
/ 16 ноября 2011

Если вы используете Linux, я бы порекомендовал использовать вырезать и вставить (командная строка). Смотрите справочные страницы.

В качестве альтернативы, если вам не нужна автоматизация, вы можете использовать режим вырезания и вставки vim block mode. Войдите в режим визуального блока с помощью control-v.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...