0

操作系统:Windows 7

我需要输出两行;每个文本文件中的一个,并排。类似于此处显示的内容。

一个.txt;

1
2
3
4
5

B.txt;

A
B
C
D
E

所以我想附和;

1 A
2 B
3 C
4 D
5 E
4

4 回答 4

2

我把它弄掉了,这给了你解决这个问题的技巧。

@echo off
del file1.txt 2>nul
del file2.txt 2>nul

for %%a in (A B C D) do echo %%a>>file2.txt
for %%a in (1 2 3 4) do echo %%a>>file1.txt

@echo off
setlocal DisableDelayedExpansion
< file2.txt (
   for /F "delims=" %%a in (file1.txt) do (
      set file2Line=
      set /P file2Line=
      set "file1Line=%%a"
      setlocal EnableDelayedExpansion   
      echo(!file1Line! !file2Line!
      endlocal
   )
)
pause

del file1.txt 2>nul
del file2.txt 2>nul
goto :EOF
于 2013-07-27T05:25:52.713 回答
1

处理批处理文件的 Windows 命令处理器cmd.exe是此类文本文件合并任务的最差选择,因为它旨在执行命令和可执行文件,而不是处理文本文件。

但是如果两个合并的文件不是太大并且行不是太长,则可以使用批处理文件完成此文本行合并任务,这意味着命令ECHO输出的行必须少于 8192 个字符,不包括换行符回车符和换行。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FileA=%~dp0A.txt"
set "FileB=%~dp0B.txt"
set "ResultsFile=%~dp0Merged AB.txt"
if not exist "%FileA%" echo ERROR: Missing file: "%FileA%"& goto :EOF
if not exist "%FileB%" echo ERROR: Missing file: "%FileB%"& goto :EOF
set "FileALinesCount=0"
set "FileBLinesCount=0"
for /F "delims==" %%I in ('set Line 2^>nul') do set "%%I="
for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /R /N "^" "%FileA%"') do for /F delims^=:^ eol^= %%J in ("%%I") do set "LineA%%J=%%I" & set "FileALinesCount=%%J"
for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /R /N "^" "%FileB%"') do for /F delims^=:^ eol^= %%J in ("%%I") do set "LineB%%J=%%I" & set "FileBLinesCount=%%J"
if %FileALinesCount% GEQ %FileBLinesCount% (set "LinesCount=%FileALinesCount%") else set "LinesCount=%FileBLinesCount%"
if %LinesCount% == 0 del "%ResultsFile%" 2>nul & goto :EOF
setlocal EnableDelayedExpansion
(for /L %%I in (1,1,%LinesCount%) do (
    if defined LineA%%I (
        if defined LineB%%I (
            echo(!LineA%%I:*:=! !LineB%%I:*:=!
        ) else echo(!LineA%%I:*:=!
    ) else echo(!LineB%%I:*:=!
))>"%ResultsFile%"
endlocal
endlocal

该批处理文件首先通过禁用命令回显模式、启用命令扩展和禁用延迟环境变量扩展来定义所需的执行环境。

接下来检查文件A.txt和是否B.txt都存在于批处理文件的目录中,否则会输出错误消息并结束批处理文件处理。

第一个FOR循环删除所有环境变量,这些环境变量偶然已经以 . 开头的名称定义Line

第二个FOR循环在后台再运行一个命令进程,%ComSpec% /c并将FINDSTR命令行作为附加参数附加,它只输出所有行号和文件冒号的行A.txt。输出行由FOR捕获并完全分配给循环变量I。对于每一行,再使用一个FOR来获取留给冒号的行号,然后定义一个环境变量,其名称LineA和行号附加FINDSTR的整行输出作为值。当前行号额外分配给环境变量FileALinesCount

第三个FOR循环对 file 中的所有行执行相同的操作B.txt

每个文件的行数可能不同。出于这个原因,IF条件找出最大的行计数值并将其分配给环境变量LinesCount

结果文件在文件上已经存在(从批处理文件的先前执行)上被删除,A.txt并且B.txt两者都存在,但都是空文件。

现在,在启用了延迟环境变量扩展的环境中使用了另一个FOR循环,以输出合并在一行上的两个文件中的行,并在它们之间使用空格字符。如果 fileA.txt的行数多于 file B.txt,则A.txt如果 file 中没有更多行,则仅输出file 的行B.txt。如果 fileB.txt的行数多于 file A.txt,则B.txt如果 file 中没有更多行,则仅输出file 的行A.txt。输出行被写入批处理文件顶部定义的结果文件。FINDSTR添加的行号和冒号在所有行输出到后台命令过程的标准输出流时,通过使用字符串替换在行输出期间删除。

要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • call /?... 解释%~dp0... 参数 0 的驱动器和路径,即批处理文件路径
  • del /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • if /?
  • set /?
  • setlocal /?

另请参阅:如何逐行读取和打印文本文件的内容?


可以在 Microsoft 文档页面上阅读有关行长限制的一些附加信息:

命令SET或命令ECHO的参数字符串不能超过 8191 个字符。

在上面的批处理文件代码中,命令SET的参数字符串是后面的所有内容,set以及将命令与其参数分开的空格字符,即引号"、变量名、等号=、字符串值和引号"

命令ECHO的参数字符串在批处理文件中命令之后的所有内容echo,左括号(用作分隔符而不是空格字符以输出正确的空行或以 开头的行/?

这是一个示例来演示 8191 个字符的命令行参数字符串长度限制。

有一个LengthTest.cmd带有以下命令行的批处理文件:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "InputFile=%~dp0Length Test Input.txt"
if not exist "%InputFile%" goto :EOF
set "OutputFile=%~dp0Length Test Output"
del "%OutputFile% *.txt" 2>nul
(for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I
    set "Line=%%I"
    echo(!Line!
))>"%OutputFile% 1_1.txt"
(for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I
    set Line=%%I
    echo(!Line!
))>"%OutputFile% 2_1.txt"
(for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I
    set L=%%I
    echo(!L!
))>"%OutputFile% 3_1.txt"
(for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I
    set L=%%I
    echo(!L! !L!
))>"%OutputFile% 4_1.txt"
(for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I
))>"%OutputFile% 5_1.txt"
for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I>>"%OutputFile% 1_2.txt"
    set "Line=%%I"
    echo(!Line!>>"%OutputFile% 1_2.txt"
)
for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I>>"%OutputFile% 2_2.txt"
    set Line=%%I
    echo(!Line!>>"%OutputFile% 2_2.txt"
)
for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I>>"%OutputFile% 3_2.txt"
    set L=%%I
    echo(!L!>>"%OutputFile% 3_2.txt"
)
for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I>>"%OutputFile% 4_2.txt"
    set L=%%I
    echo(!L! !L!>>"%OutputFile% 4_2.txt"
)
for /F "usebackq delims=" %%I in ("%InputFile%") do (
    echo(%%I>>"%OutputFile% 5_2.txt"
)
endlocal

在这个批处理文件的目录中是一个文本文件Length Test Input.txt,它有六行以回车和换行结束。这六行是:

Line 1 - 8184 chars: 0123456789...0123456789abc
Line 2 - 8186 chars: 0123456789...0123456789abcde
Line 3 - 8189 chars: 0123456789...0123456789abcdefgh
Line 4 - 8190 chars: 0123456789...0123456789abcdefghi
Line 5 - 8191 chars: 0123456789...0123456789abcdefghij
Line 6 - 8192 chars: 0123456789...0123456789abcdefghijk

...在这里用作 814 次重复的占位符0123456789

该批处理文件的执行产生十个文件。

  1. Length Test Output 1_1.txtLength Test Output 1_2.txt包含:

    Line 1 - 8184 chars: 0123456789...0123456789abc
    Line 1 - 8184 chars: 0123456789...0123456789abc
    
  2. Length Test Output 2_1.txtLength Test Output 2_2.txt包含:

    Line 1 - 8184 chars: 0123456789...0123456789abc
    Line 1 - 8184 chars: 0123456789...0123456789abc
    Line 2 - 8186 chars: 0123456789...0123456789abcde
    Line 2 - 8186 chars: 0123456789...0123456789abcde
    
  3. Length Test Output 3_1.txtLength Test Output 3_2.txt包含:

    Line 1 - 8184 chars: 0123456789...0123456789abc
    Line 1 - 8184 chars: 0123456789...0123456789abc
    Line 2 - 8186 chars: 0123456789...0123456789abcde
    Line 2 - 8186 chars: 0123456789...0123456789abcde
    Line 3 - 8189 chars: 0123456789...0123456789abcdefgh
    Line 3 - 8189 chars: 0123456789...0123456789abcdefgh
    
  4. Length Test Output 4_1.txtLength Test Output 4_2.txt包含:

    Line 1 - 8184 chars: 0123456789...0123456789abc
    Line 2 - 8186 chars: 0123456789...0123456789abcde
    Line 3 - 8189 chars: 0123456789...0123456789abcdefgh
    
  5. Length Test Output 5_1.txtLength Test Output 5_2.txt包含:

    Line 1 - 8184 chars: 0123456789...0123456789abc
    Line 2 - 8186 chars: 0123456789...0123456789abcde
    Line 3 - 8189 chars: 0123456789...0123456789abcdefgh
    Line 4 - 8190 chars: 0123456789...0123456789abcdefghi
    Line 5 - 8191 chars: 0123456789...0123456789abcdefghij
    

结论:

  1. 包含 8192 个字符的第六行太长,Windows 命令处理器根本无法处理。
  2. 如果在FOR循环中使用ECHO输出的所有内容首先被捕获然后写入文件(文件),或者每个输出在处理小文件时直接写入文件(文件),则对创建文件的内容没有影响文件。cmd.exe*_1.txt*_2.txt
  3. 带有超过 8191 个字符的命令ECHOecho(!L! !L!的行的输出失败,如 所示。这两个创建的输出文件Length Test Output 4_1.txtLength Test Output 4_2.txt包含echo(%%I两个循环中输出的行。
  4. 带有命令SETFOR循环,如果SET处理的参数字符串超过 8191 个字符,则会导致在执行循环体中的任何命令之前退出循环。我很确定绝大多数批处理文件程序员绝对不会期望 Windows 命令处理器的这种行为。

批处理文件LengthTest.cmd在 Windows XP SP3、Windows 7 SP1 和 Windows 10 1909 上生成相同的十个文件。

于 2021-08-27T06:20:44.273 回答
0

尝试这个:

@echo off
setlocal enabledelayedexpansion
set /a count=0

For /f %%a in (A.txt) do (
set /a count=!count!+1
set A!count!=%%a
)
set count=0
For /f %%b in (B.txt) do (
set /a count=!count!+1
set B!count!=%%b
)
set recount=0
:loop
recount=%recount%+1
echo %A!recount!% %B!recount!%
if %recount% gtr %count% goto :end
goto :recount
:end
pause
exit

希望这有帮助,

你的莫娜

注意:如果有更多的行,A.txt那么它将忽略它们。如果少了会显示[blank] [line from B.txt]

于 2013-07-27T05:30:35.477 回答
0

GNU 的代码:

sed "s#.*#s/.*/& \&/g;n#" A.txt|sed -f - B.txt

>sed "s#.*#s/.*/& \&/g;n#" A.txt|sed -f - B.txt
1个
2乙
3℃
4 天
5 E
于 2013-07-27T07:37:45.147 回答