如何通过批处理文件并行读取两个文本文件?

3

有没有一种简单而高效的方法可以并行地逐行读取两个(甚至更多)文本文件?因此,每次迭代都需要循环读取每个文本文件的一行。

不能使用给定多个文件的for /F循环,因为这会依次读取文件。当然,嵌套这样的循环也没有意义。

1个回答

6
关键是使用STDIN重定向<(另请参见此网站),在整个代码块中使用未定义的句柄(39)进行文件读取,命令set / P 用于实际读取一行,在该块中使用0<&将未定义的句柄重新定向回STDIN以供set / P 使用,以便读取相应的行。

以下是它的工作原理示例:

假设有以下两个文本文件names.txt...

Black
Blue
Green
Aqua
Red
Purple
Yellow
White
Grey
Brown

...和 values.txt...

0
1
2
3
4
5
6
7

...目标是将它们逐行组合以实现此文件,names=values.txt...

Black=0
Blue=1
Green=2
Aqua=3
Red=4
Purple=5
Yellow=6
White=7
以下代码可以实现这一点(请查看所有的解释性注释,rem):
@echo off
setlocal EnableExtensions EnableDelayedExpansion

rem // Define constants here:
set "FILE1=names.txt"
set "FILE2=values.txt"
set "RET=names=values.txt" & rem // (none to output to console)
if not defined RET set "RET=con"

rem /* Count number of lines of 1st file (2nd file is not checked);
rem    this is necessary to know when to stop reading: */
for /F %%C in ('^< "%FILE1%" find /C /V ""') do set "NUM1=%%C"

rem /* Here input redirection is used, each file gets its individual
rem    (undefined) handle (that is not used by the system) which is later
rem    redirected to handle `0`, `STDIN`, in the parenthesised block;
rem    so the 1st file data stream is redirected to handle `4` and the
rem    2nd file to handle `3`; within the block, as soon as a line is read
rem    by `set /P` from a data stream, the respective handle is redirected
rem    back to `0`, `STDIN`, where `set /P` expects its input data: */
4< "%FILE1%" 3< "%FILE2%" > "%RET%" (
     rem // Loop through the number of lines of the 1st file:
     for /L %%I in (1,1,%NUM1%) do (
         set "LINE1=" & rem /* (clear variable to maintain empty lines;
                        rem     `set /P` does not change variable value
                        rem     in case nothing is entered/redirected) */
         rem // Change handle of 1st file back to `STDIN` and read line:
         0<&4 set /P "LINE1="
         set "LINE2=" & rem // (clear variable to maintain empty lines)
         rem // Change handle of 2nd file back to `STDIN` and read line:
         0<&3 set /P "LINE2="
         rem /* Return combined pair of lines (only if line of 2nd file is
         rem    not empty as `set /P` sets `ErrorLevel` on empty input): */
         if not ErrorLevel 1 echo(!LINE1!=!LINE2!
     )
)

endlocal
exit /B

3
是的,这种方法已经在这里 http://stackoverflow.com/questions/32738831/extracting-all-lines-from-multiples-files/32739680#32739680,或者在这里 https://dev59.com/iG3Xa4cB1Zd3GeqPhKmg#14523100,或者在这里 http://stackoverflow.com/questions/28850167/solved-merge-several-csv-file-side-by-side-using-batch-file/28864990#28864990,或者在这里 http://stackoverflow.com/questions/32238565/windows-batch-file-combine-csv-in-a-folder-by-column/32254700#32254700,或者在这里 http://www.dostips.com/forum/viewtopic.php?f=3&t=3126 已经被使用过了。 - Aacini
@Aacini,谢谢你提供的链接!看起来我在这里使用了错误的搜索词(_parallel_,_simultaneous_,_concurrent_,...);在这里只是以合并文件作为一个例子... - aschipfl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接