Batch file 真正合并到.bat文件中

Batch file 真正合并到.bat文件中,batch-file,Batch File,如何将两个文本文件合并到一个.bat文件中? 或者至少如何读取.bat文件中文件的下一行/测试结尾 是否可以使用.bat脚本合并两个文本文件? 其思想不是附加或连接,而是基于每行的内容执行合并操作。 一个简化的示例是从两个排序文件生成一个排序文件,如伪代码(伪代码,因为我似乎找不到读取下一行并测试读取文件结尾的方法–在for循环之外) :顶部 设置/p行1读取行(文件1) :设置/p行2读取行(文件2) :测试 如果EOF(文件1)转到FINISH2 如果EOF(文件2)转到FINISH1 如果

如何将两个文本文件合并到一个.bat文件中? 或者至少如何读取.bat文件中文件的下一行/测试结尾

是否可以使用.bat脚本合并两个文本文件? 其思想不是附加或连接,而是基于每行的内容执行合并操作。 一个简化的示例是从两个排序文件生成一个排序文件,如伪代码(伪代码,因为我似乎找不到读取下一行并测试读取文件结尾的方法–在for循环之外)

:顶部
设置/p行1读取行(文件1)
:设置/p行2读取行(文件2)
:测试
如果EOF(文件1)转到FINISH2
如果EOF(文件2)转到FINISH1
如果%Line1%<%Line2%
(回显%Line1%-不在2>>文件3中
设置/p行1=读取行(文件1)
转到测试)
如果%Line1%>%Line2%
(回显%Line2%-不在1>>文件3中
设置/p行2=读取行(文件2)
转到测试)
ELSE在两个>>文件中都回显%Line1%3
转到顶端
:FINISH1
回显%Line2%-不在1>>文件3中
设置/p行1=读取行(文件1)
如果不是(EOF(文件1))
(回显%Line1%-不在2>>文件3中
转到完成1)
否则转到EOF
:FINISH2
回显%Line2%-不在1>>文件3中
设置/p行2=读取行(文件2)
如果不是(EOF(文件1))
(回显%Line2%-不在1>>文件3中
GOTO FINISH2)
我尝试了for循环,但是循环内部的分支似乎阻止了循环。我尝试了各种方法(包括parallel.bat)来找到一种方法,使用
set
2个步骤在文件中移动光标(不需要排序,因为步骤2中的
find
会检查新文件,只有在找不到数据时才会写入内容):

  • 合并文件:
    copy file1.txt+file2.txt file3.txt

  • 删除重复行(
    /i
    忽略大小写,如果将
    Fred
    Fred
    视为不同,则省略):

  • 结果文件为
    file4.txt

    2个步骤(不需要排序,因为步骤2中的
    find
    检查新文件,并且仅在未找到数据时写入内容):

  • 合并文件:
    copy file1.txt+file2.txt file3.txt

  • 删除重复行(
    /i
    忽略大小写,如果将
    Fred
    Fred
    视为不同,则省略):


  • 结果文件是
    file4.txt

    批处理对于文本处理来说确实是一种糟糕的“语言”。几乎你能找到的任何其他工具都比批处理更好(更容易开发,执行更快)。我提供批处理解决方案是因为我喜欢这个挑战,但我总是会推荐一些其他语言或工具来代替批处理来进行文本处理。话虽如此

    假设两个源文件都已排序

    @echo off
    setlocal enableDelayedExpansion
    
    ::define the files
    set "in1=file1.txt"
    set "in2=file2.txt"
    set "out=file3.txt"
    
    ::define some simple macros
    set "eof1=^!ln1^! gtr ^!cnt1^!"
    set "eof2=^!ln2^! gtr ^!cnt2^!"
    set "read1=if ^!ln1^! leq ^!cnt1^! set "txt1=" & <&3 set /p "txt1=" & set /a ln1+=1"
    set "read2=if ^!ln2^! leq ^!cnt2^! set "txt2=" & <&4 set /p "txt2=" & set /a ln2+=1"
    set "write1=echo(^!txt1^! - not in 2"
    set "write2=echo(^!txt2^! - not in 1"
    set "writeBoth=echo(^!txt1^! - in both"
    
    ::count the number of lines in each file
    for /f %%N in ('find /v /c "" ^<"%in1%"') do set "cnt1=%%N"
    for /f %%N in ('find /v /c "" ^<"%in2%"') do set "cnt2=%%N"
    
    ::setup redirection in outer block and merge the files in a loop
    ::The max number of iterations assumes there is no overlap (cnt1+cnt2)
    ::Break out of the loop as soon as both files have reached EOF.
    set /a ln1=0, ln2=0, cnt=cnt1+cnt2
    4<"%in2%" 3<"%in1%" (
      %read1%
      %read2%
      for /l %%N in (1 1 %cnt%) do (
        if %eof1% (
            if %eof2% goto :break
            %write2%
            %read2%
        ) else if %eof2% (
            %write1%
            %read1%
        ) else if .!txt1! lss .!txt2! (
            %write1%
            %read1%
        ) else if .!txt2! lss .!txt1! (
            %write2%
            %read2%
        ) else (
            %writeBoth%
            %read1%
            %read2%
        )
      )
    ) >"%out%
    :break
    

    对于文本处理来说,批处理确实是一种糟糕的“语言”。几乎你能找到的任何其他工具都比批处理更好(更容易开发,执行更快)。我提供批处理解决方案是因为我喜欢这个挑战,但我总是会推荐一些其他语言或工具来代替批处理来进行文本处理。话虽如此

    假设两个源文件都已排序

    @echo off
    setlocal enableDelayedExpansion
    
    ::define the files
    set "in1=file1.txt"
    set "in2=file2.txt"
    set "out=file3.txt"
    
    ::define some simple macros
    set "eof1=^!ln1^! gtr ^!cnt1^!"
    set "eof2=^!ln2^! gtr ^!cnt2^!"
    set "read1=if ^!ln1^! leq ^!cnt1^! set "txt1=" & <&3 set /p "txt1=" & set /a ln1+=1"
    set "read2=if ^!ln2^! leq ^!cnt2^! set "txt2=" & <&4 set /p "txt2=" & set /a ln2+=1"
    set "write1=echo(^!txt1^! - not in 2"
    set "write2=echo(^!txt2^! - not in 1"
    set "writeBoth=echo(^!txt1^! - in both"
    
    ::count the number of lines in each file
    for /f %%N in ('find /v /c "" ^<"%in1%"') do set "cnt1=%%N"
    for /f %%N in ('find /v /c "" ^<"%in2%"') do set "cnt2=%%N"
    
    ::setup redirection in outer block and merge the files in a loop
    ::The max number of iterations assumes there is no overlap (cnt1+cnt2)
    ::Break out of the loop as soon as both files have reached EOF.
    set /a ln1=0, ln2=0, cnt=cnt1+cnt2
    4<"%in2%" 3<"%in1%" (
      %read1%
      %read2%
      for /l %%N in (1 1 %cnt%) do (
        if %eof1% (
            if %eof2% goto :break
            %write2%
            %read2%
        ) else if %eof2% (
            %write1%
            %read1%
        ) else if .!txt1! lss .!txt2! (
            %write1%
            %read1%
        ) else if .!txt2! lss .!txt1! (
            %write2%
            %read2%
        ) else (
            %writeBoth%
            %read1%
            %read2%
        )
      )
    ) >"%out%
    :break
    

    为什么不简单地使用diff/merge实用程序呢?欢迎用户1495762。请使用编辑框上方的按钮提供的这一面的标记,但不要使用一些不起作用的自创语法。有关更多信息,请阅读常见问题解答。谢谢。这里有一些GNU工具:
    join
    sort-m
    combine
    等等。你可以获得我安装的cygwin的大部分信息。cygwin还提供了一个更好的shell/命令行解释器,名为bash。
    sort
    也在dos中使用了很长一段时间——在XP中,它将是
    copy file1.txt+file2.txt file3.txt
    然后
    sortedfile3.txt/o sortedfile3.txt
    ,原始文件不需要sorted@SeanCheshire-但这不会合并文件。如果一行同时出现在两个源中,则在输出中只应出现一次。您的建议将在输出中放置该行的两个副本。为什么不简单地使用diff/merge实用程序呢?欢迎使用1495762。请使用编辑框上方的按钮提供的这一面的标记,但不要使用一些不起作用的自创语法。有关更多信息,请阅读常见问题解答。谢谢。这里有一些GNU工具:
    join
    sort-m
    combine
    等等。你可以获得我安装的cygwin的大部分信息。cygwin还提供了一个更好的shell/命令行解释器,名为bash。
    sort
    也在dos中使用了很长一段时间——在XP中,它将是
    copy file1.txt+file2.txt file3.txt
    然后
    sortedfile3.txt/o sortedfile3.txt
    ,原始文件不需要sorted@SeanCheshire-但这不会合并文件。如果一行同时出现在两个源中,则在输出中只应出现一次。您的建议将在输出中放置该行的2个副本。+1,简单合并的优雅解决方案,假设所有DUP都应删除。虽然不确定性能,但为每行调用FIND可能会大大降低速度。这不能像OP最初在伪代码中显示的那样跟踪哪些行来自何处。使用“复制”选项可防止添加
    。循环体可以简化为
    find/i“%%a”file4.txt>nul | echo%%a>>file4.txt
    woops,最终输出需要排序以满足操作要求
    sort file4.txt/o file5.txt
    ,但您的解决方案更优雅+1,简单合并的优雅解决方案,假设所有DUP都应该删除。虽然不确定性能,但为每行调用FIND可能会大大降低速度。这不能像OP最初在伪代码中显示的那样跟踪哪些行来自何处。使用“复制”选项可防止添加
    。循环体可以简化为
    find/i“%%a”file4.txt>nul | | echo%%a>>file4.txt
    woops,final
    @echo off
    setlocal enableDelayedExpansion
    
    ::define the files
    set "in1=file1.txt"
    set "in2=file2.txt"
    set "out=file3.txt"
    
    ::define some simple macros
    set "eof1=^!ln1^! gtr ^!cnt1^!"
    set "eof2=^!ln2^! gtr ^!cnt2^!"
    set "read1=if ^!ln1^! leq ^!cnt1^! set "txt1=" & <&3 set /p "txt1=" & set /a ln1+=1"
    set "read2=if ^!ln2^! leq ^!cnt2^! set "txt2=" & <&4 set /p "txt2=" & set /a ln2+=1"
    set "write1=echo(^!txt1^! - not in 2"
    set "write2=echo(^!txt2^! - not in 1"
    set "writeBoth=echo(^!txt1^! - in both"
    
    ::count the number of lines in each file
    for /f %%N in ('find /v /c "" ^<"%in1%"') do set "cnt1=%%N"
    for /f %%N in ('find /v /c "" ^<"%in2%"') do set "cnt2=%%N"
    
    ::setup redirection in outer block and merge the files in a loop
    ::The max number of iterations assumes there is no overlap (cnt1+cnt2)
    ::Break out of the loop as soon as both files have reached EOF.
    set /a ln1=0, ln2=0, cnt=cnt1+cnt2
    4<"%in2%" 3<"%in1%" (
      %read1%
      %read2%
      for /l %%N in (1 1 %cnt%) do (
        if %eof1% (
            if %eof2% goto :break
            %write2%
            %read2%
        ) else if %eof2% (
            %write1%
            %read1%
        ) else if .!txt1! lss .!txt2! (
            %write1%
            %read1%
        ) else if .!txt2! lss .!txt1! (
            %write2%
            %read2%
        ) else (
            %writeBoth%
            %read1%
            %read2%
        )
      )
    ) >"%out%
    :break
    
    @echo off
    setlocal disableDelayedExpansion
    set lf=^
    
    
    ::above 2 blank lines required
    copy /b file1.txt+file2.txt file3.txt >nul
    set "old="
    (
      for /f eol^=^%lf%%lf%^ delims^= %%A in ('sort file3.txt') do (
        set "new=.%%A"
        setlocal enableDelayedExpansion
        if "!old!" neq "!new!" echo(!new:~1!
        for /f "delims=" %%B in ("!new!") do (
          endlocal
          set "old=%%B"
        )
      )
    )>file4.txt