简体   繁体   English

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

[英]How can two text files be read in parallel by a batch file?

Is there a simple and good-performing way to read two (or even more) text files line by line in parallel?是否有一种简单且性能良好的方式来并行读取两个(甚至更多)文本文件? So to have a loop that reads a single line of each text file in every iteration.所以要有一个循环,在每次迭代中读取每个文本文件的一行。

A for /F loop with multiple files given cannot be used as this reads a file after another.不能使用包含多个文件的for /F循环,因为它会依次读取一个文件。 Nested such loops do not make sense either of course.嵌套这样的循环当然也没有意义。

The trick is to use STDIN redirection < (see also this site ) using undefined handles ( 3 to 9 ) for the entire code block for file reading, the command set /P in the block to actually read a line and 0<& to redirect the undefined handles back to STDIN for set /P , thus for the respective line to read.诀窍是使用STDIN 重定向< (另请参阅此站点),使用未定义的句柄( 39 )为整个代码块读取文件,块中的命令set /P实际读取一行, 0<&重定向未定义的句柄返回到STDINset /P ,从而读取相应的行。

Here is an example how it works:这是它如何工作的示例:

Supposing there are the following two text files names.txt ...:假设有以下两个文本文件names.txt ...:

 Black Blue Green Aqua Red Purple Yellow White Grey Brown

...and values.txt ...: ...和values.txt ...:

 0 1 2 3 4 5 6 7

...and the goal is to combine them line by line to achieve this file, names=values.txt ...: ...目标是将它们逐行组合以实现此文件, names=values.txt ...:

 Black=0 Blue=1 Green=2 Aqua=3 Red=4 Purple=5 Yellow=6 White=7

...the following code accomplishes that (see all the explanatory comments, rem ): ...以下代码实现了这一点(请参阅所有解释性注释, 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM