我知道 3 种基本技术,从中可以衍生出大量的混合体。
选项 1(这个选项与 wmz 解决方案非常相似)
使用 FOR /F 读取文件 1,并使用带有 SKIP 选项的第二个 FOR /F 读取文件 2。必须在 CALLed 子例程中读取文件 2,以便可以在不中断文件 1 循环的情况下中断循环。
限制:
- 空行会导致行不同步。空白行包含在跳过计数中,但 FOR /F 不读取。
;
由于默认的 EOL 选项,不会读取以开头的行。如有必要,可以通过将 EOL 设置为换行符来解决此问题。请参阅如何:FOR /F 禁用 EOF 或使用引号作为分隔符
- 行的最大长度限制为 8191 字节。
这个选项很慢,因为 CALL 并且因为第二个文件必须为每一行读取一次。
编辑 - 如果第二个文件提前结束,代码固定为仍然输出一行
@echo off
setlocal disableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"
set /a cnt=0
set "skip="
>"%out%" (
for /f "usebackq delims=" %%A in ("%file1%") do (
set "found="
call :readFile2
if not defined found (echo %%A - )
)
)
type "%out%"
exit /b
:readFile2
for /f "usebackq %skip% delims=" %%B in ("%file2%") do (
set found=1
echo %%A - %%B"
goto :break
)
:break
set /a cnt+=1
set "skip=skip=%cnt%"
exit /b
选项 2
此选项通过使用 FINDSTR 在每行前面加上行号和冒号来解决空行问题。FINDSTR 用于仅读取文件 2 中的第 n 行,因此无需跳出第二个循环。
限制:
- 前导冒号将从行中删除。这个限制可以通过额外的代码来消除,但它会使它变得更复杂和更慢。
- 行的最大长度限制为 8191 字节。
此选项甚至比选项 1 慢
编辑 - 如果第二个文件提前结束,代码固定为仍然输出一行
@echo off
setlocal disableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"
>"%file2%.tmp" findstr /n "^" "%file2%"
>"%out%" (
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" "%file1%"') do (
set "found="
for /f "tokens=1* delims=:" %%a in ('findstr "^%%A:" "%file2%.tmp"') do (
set found=1
echo %%B - %%b
)
if not defined found (echo %%B - )
)
)
del "%file2%.tmp"
type "%out%"
选项 3
使用 SET /P 读取这两个文件。FIND 用于获取文件 1 中的行数,因为 SET /P 无法区分空行和文件结尾之间的区别。
此选项消除了许多限制和复杂性,但引入了其自身的限制。
限制:
- 行必须使用
<CR><LF>
. Unix 风格<LF>
行不通。
- 行限制为 1021 字节
- 从每一行中去除尾随控制字符。
这个选项是迄今为止最快的。只要限制是可以接受的,它是优选的。
@echo off
setlocal enableDelayedExpansion
set "file1=a.txt"
set "file2=b.txt"
set "out=out.txt"
for /f %%N in ('type "%file1%"^|find /c /v ""') do set "cnt=%%N"
>"%out%" 9<"%file1%" <"%file2%" (
for /l %%N in (1 1 %cnt%) do (
set "ln1="
set "ln2="
<&9 set /p "ln1="
set /p "ln2="
echo !ln1! - !ln2!
)
)
type "%out%"