【问题标题】:Batch script to merge lines from two files into a third file将两个文件中的行合并到第三个文件中的批处理脚本
【发布时间】:2011-11-16 14:01:18
【问题描述】:

文件A1的内容:

AA
VV
BB

文件A2的内容:

DD
EE
FF

我想将下面A1A2的内容合并到A3中,这样A3中的预期数据是:

AADD
VVEE
BBFF

或者,A3 中的预期输出可能是:

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

感谢您的帮助。我在发布之前确实尝试过搜索,但找不到已经发布过类似内容的人...

【问题讨论】:

  • 这不是“将多个文件复制为一个”。它是“将两个文件中的行合并到第三个文件中”。

标签: file batch-file merge


【解决方案1】:

我们可以将文件的内容加载到 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

编辑 替代解决方案

还有另一种不使用批处理变量的方法,因此它可以用于任何大小的文件,但速度较慢。我借用了 Andy Morris 在其解决方案中使用的方法:1- 在两个文件中插入行号,2- 将两个文件合并为一个,3- 对合并的文件进行排序,以及 4- 将多组行合并到同一行中。下面的程序基本上是 Andy 的程序,做了一些小的修改,使其更快(修复了一个细微的错误)。

@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

根据其内容对命令行进行排序。 Andy 的原始方法可能会失败,因为行号之后的行是根据行内容排序的,因此每个文件的行可能会放错位置。在此方法中,在行号之后添加了一个附加字符(A 或 B),因此每个文件的行总是放在正确的位置。

【讨论】:

  • 不错的做法,可能会对大文件感兴趣。从microsoft.com/resources/documentation/windows/xp/all/proddocs/… 开始,所有变量的最大环境变量总大小(包括变量名和等号)为 65,536KB。但可能会更快达到该限制
  • 关于排序的行排序的要点。不确定我是否费心优化,但你有一些有趣的技术。
【解决方案2】:

如果您的原始数据在 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

【讨论】:

    【解决方案3】:

    如果使用 linux,我建议使用剪切和粘贴(命令行)。请参阅手册页。

    或者,如果您不需要自动化,您可以使用 vim 块模式剪切和粘贴。使用 control-v 进入块模式视觉模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-22
      • 1970-01-01
      • 2021-10-19
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多