我相信这与批处理解决方案一样强大。
- 它处理两个文件中的空行
- 每行最多可以读取大约 8k 字节
- 文件中的行数不必匹配
- 一行可以以任何字符开头(避免 FOR /F EOL 问题)
- 一行可以包含
!
而不会损坏(避免在启用延迟扩展时扩展 FOR 变量的问题)
- 行可以是 Unix 或 Windows 样式。
- 控制字符不会从行尾剥离
但是这个解决方案在读取一个大文件时会变得越来越慢,因为它必须从头开始重新扫描第二个文件的每一行。
@echo off
setlocal disableDelayedExpansion
set "file1=file1.txt"
set "file2=file2.txt"
for /f %%N in ('find /c /v "" ^<"%file2%"') do set file2Cnt=%%N
findstr /n "^" "%file1%" >"%file1%.tmp"
findstr /n "^" "%file2%" >"%file2%.tmp"
set "skip=0"
set "skipStr="
for /f "usebackq delims=" %%A in ("%file1%.tmp") do (
set "ln1=%%A"
call :readFile2
set /a "skip+=1"
)
if %file2Cnt% gtr %skip% (
for /f "usebackq skip=%skip% delims=" %%B in ("%file2%.tmp") do (
set "ln2=%%B"
setlocal enableDelayedExpansion
set "ln2=!ln2:*:=!"
(echo()
(echo(!ln2!)
)
)
del "%file1%.tmp" 2>nul
del "%file2%.tmp" 2>nul
exit /b
:readFile2
if %skip% gtr 0 set "skipStr=skip=%skip% "
if %file2Cnt% gtr %skip% (
for /f "usebackq %skipStr%delims=" %%B in ("%file2%.tmp") do (
set "ln2=%%B"
goto :break
)
) else set "ln2="
:break
setlocal enableDelayedExpansion
set "ln1=!ln1:*:=!"
if defined ln2 set "ln2=!ln2:*:=!"
(echo(!ln1!)
(echo(!ln2!)
exit /b
如果该解决方案的限制与您的文件无关,那么使用jeb 的方法会更好。它目前具有以下限制,可以通过相当小的修改来消除:
- 文件必须具有相同的行数
- 文件不能有空行
- File1 不能包含
!
字符
- File1 中的任何行都不能以
;
此外,它在读取 File2 时具有以下限制,这些限制是 SET /P 限制所固有的
- 行必须是 Windows 样式,以回车符结尾 lineFeed
- 行不能超过 1021 个字符(字节),不包括行终止符
- 控制字符将从每行的末尾剥离
一个更好的解决方案是使用批处理以外的东西。有很多可能性:VBS、JScript、PowerShell、perl……不胜枚举。