2016-07-06 5 views
2

Есть ли простой и эффективный способ чтения двух (или даже более) текстовых файлов по очереди параллельно? Итак, чтобы иметь цикл, который читает одну строку каждого текстового файла на каждой итерации.Как два текстовых файла могут быть прочитаны параллельно пакетным файлом?

A for /F цикл с несколькими указанными файлами не может использоваться, поскольку это считывает файл за другим. Вложенные такие петли не имеют смысла, конечно.

ответ

2

Хитрость заключается в том, чтобы использовать STDINredirection< (смотри также this site) с помощью неопределенных ручки (3 к 9) для всего блока кода для чтения файла, команду 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 
+2

Да, этот метод уже использовался [здесь] (http://stackoverflow.com/questions/32738831/extracting-all-lines-from-multiples-files/32739680#32739680) , или [здесь] (http://stackoverflow.com/questions/14521799/comb inining-multiple-text-files-in-one/14523100 # 14523100) или [здесь] (http://stackoverflow.com/questions/28850167/solved-merge-several-csv-file-side-by-side-side-side-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

+0

@Aacini, спасибо за ссылки! кажется, что я использовал здесь неправильные условия поиска (_parallel_, _simultaneous_, _concurrent _, ...); _combining_ файлы просто используются в качестве примера здесь ... – aschipfl