Batch file 在许多大文本文件上运行多个管道命令的快速方法

Batch file 在许多大文本文件上运行多个管道命令的快速方法,batch-file,visual-c++,parallel-processing,Batch File,Visual C++,Parallel Processing,我在文本文件中存储了大量数据(每个文件中有一天的数据,最大大小约为1.5gb)。它们是数据源,因此必须处理为人类可读的格式,这是由几个C程序(不是我写的)完成的 通过f.ex运行命令,我获得了一天的特定数据 decode.exe < ResourceTXT/itch-20140530.txt | select.exe -I 101 | bookgen.exe -t -r | dump.exe > Output/20140530.txt 给我输出 decode.exe < R

我在文本文件中存储了大量数据(每个文件中有一天的数据,最大大小约为1.5gb)。它们是数据源,因此必须处理为人类可读的格式,这是由几个C程序(不是我写的)完成的

通过f.ex运行命令,我获得了一天的特定数据

decode.exe < ResourceTXT/itch-20140530.txt | select.exe -I 101 | bookgen.exe  -t -r | dump.exe > Output/20140530.txt
给我输出

decode.exe < ResourceTXT/itch-20140530.txt | select.exe -I 101 | bookgen.exe  -t -r | dump.exe > Output/20140530.txt
decode.exe < ResourceTXT/itch-20140531.txt | select.exe -I 101 | bookgen.exe  -t -r | dump.exe > Output/20140531.txt
decode.exe < ResourceTXT/itch-20140601.txt | select.exe -I 101 | bookgen.exe  -t -r | dump.exe > Output/20140601.txt
然后删除中间的.txt文件,我就完成了

但如果我需要生成100天的数据,这是一种非常缓慢的方法

我知道我可以用start命令启动100个windows命令实例。但是为了在这里工作,我需要创建100个.bat文件,每个文件都包含要运行的“查询”,然后创建另一个final.bat文件,启动所有这些bat文件,如:

start batfile1.bat
start batfile2.bat
...
start batfile100.bat
然后跑final.bat

这感觉像是一个笨重和有点不雅观的方式来做。因为我是一个新手,我想确认一下,这是否是一个解决我问题的好方法,或者我是否在做一些非常愚蠢的事情,或者忽略了任何重要的事情。多谢各位

注:我正在帮助一个这样的家伙,他希望把所有东西都放在VisualC++项目中(原始C程序来处理原始数据提要[CODDE.EXE等]已经被移植到这个项目中)。这意味着所有的事情都应该用C++或Windows批处理文件来完成。p> 编辑: 以下是Aacini要求的信息:

第一种方法:

Start: 16:01:12,62
End:   16:02:02,12
第二种方法:

Start decode:  16:03:32,05
Start select:  16:04:28,49
Start bookgen: 16:04:37,11
Start dump:    16:04:37,35
End:           16:04:38,04

哇,看来最好是在每个文本文件上运行decode.exe,并存储二进制数据以供以后使用。。。?(但另一个问题是,这些二进制编码文件实际上是.txt文件中原始数据大小的两倍…

为了提高方法的效率,您可以测试几个要点

首先,由管道连接的几个过程的效率取决于几个因素,但无论如何,最终结果总是与最慢的过程联系在一起。这意味着,如果我们确定最慢的进程并给它更多的CPU时间,我们可以提高总体效率

您可以开始执行一些计时测试;例如,首先通过以下方式测试原始方法:

echo Start: %time%
decode.exe < ResourceTXT/itch-20140530.txt | select.exe -I 101 | bookgen.exe  -t -r | dump.exe > Output/20140530.txt
echo End:   %time%
我建议你做一些测试,处理文件大约15-20天。从8个活动实例开始,等待1秒,然后重复测试,增加1个实例,减少1个实例。如果其中一个更改导致总时间减少,则在同一方向上用1个实例重复测试。找到最佳实例数后,执行类似的测试,增加等待的秒数。之后,您可以以最快的方式处理100个或任意数量的文件


如果您能发布一些测试结果,我将不胜感激。如果您有任何问题,请给我留言。

我已经编辑了我的帖子。非常感谢。echo%NUMBER\u OF_Processor%给出8Ok。对于8个核心,我们可能有1个核心运行
选择| bookgen | dump
,其余核心运行
解码
的实例;这意味着在给定的时刻,可能会有多达7个不同的
temp1.txt
文件,尽管它们中的每一个都将在
select |…
处理后立即被删除。所以重要的问题是:是否有足够的可用磁盘空间供所有人使用?是的,磁盘空间不应该是一个限制。非常感谢,很抱歉回复得很晚。我已经尝试过你的方法,它似乎工作得很好,但我将不得不花一些时间来理解整个脚本。再次感谢
Start decode:  16:03:32,05
Start select:  16:04:28,49
Start bookgen: 16:04:37,11
Start dump:    16:04:37,35
End:           16:04:38,04
echo Start: %time%
decode.exe < ResourceTXT/itch-20140530.txt | select.exe -I 101 | bookgen.exe  -t -r | dump.exe > Output/20140530.txt
echo End:   %time%
echo Start decode:  %time%
decode.exe < ResourceTXT/itch-20140530.txt > temp1.txt
echo Start select:  %time%
select.exe -I 101 < temp1.txt > temp2.txt
echo Start bookgen: %time%
bookgen.exe  -t -r < temp2.txt > temp3.txt
echo Start dump:    %time%
dump.exe < temp3.txt > Output/20140530.txt
echo End:           %time%
@echo off
setlocal EnableDelayedExpansion

if "%~4" neq "" goto begin

echo Usage: %0 numOfProcesses secondsToWait startDate endDate [options]
echo/
echo    numOfProcesses - Number of simultaneous queries to run in parallel
echo    secondsToWait  - Seconds to wait between process checking
echo    start/end Date - In YYYYMMDD format
echo    options        - First options are for select.exe, followed by
echo                     B opts for bookgen.exe, and D opts for dump.exe
echo/
echo For example:
echo    %0 8 10 20140530 20140601 -I 101 B -t -r
goto :EOF

:begin

set    "maxProcs=%1"  & shift
set /A "seconds=%1+1" & shift
set    "startDate=%1" & shift
set    "endDate=%1"

rem Get the options for each process
set "proc=S"
set "procs= B D "
:nextOpt
   shift
   if "%1" equ "" goto continue
   if "!procs: %1 =!" neq "%procs%" (
      set "proc=%1"
   ) else (
      set "%proc%_opts=!%proc%_opts! %1"
   )
goto nextOpt
:continue

rem Initialize date variables
set M=100
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do (
   set /A M+=1
   set "daysPerMonth[!M!]=1%%a"
)
set /A Y=%startDate:~0,4%, M=1%startDate:~4,2%, D=1%startDate:~6,2%, leap=Y%%4
if %leap% equ 0 set "daysPerMonth[102]=129"

rem Start the initial set of N parallel processes
del query.log *.flg 2> NUL
set startTime=%time%
set /A query=0, active=0
:nextQuery
   set /A query+=1
   echo %query%- %Y%%M:~1%%D:~1% Started @ %time% >> query.log
   echo X > %Y%%M:~1%%D:~1%.flg
   start /B cmd.exe /D /C decode.exe ^< ResourceTXT/itch-%Y%%M:~1%%D:~1%.txt ^| select.exe %S_opts% ^| bookgen.exe %B_opts% ^| dump.exe %D_opts% ^> Output/%Y%%M:~1%%D:~1%.txt ^& del %Y%%M:~1%%D:~1%.flg
   ECHO Query %query%- %Y%%M:~1%%D:~1% started
   set /A D+=1
   if %D% gtr !daysPerMonth[%M%]! (
      set /A  D=101, M+=1
      if !M! gtr 112 (
         set /A M=101, Y+=1, leap=Y%%4
         if !leap! equ 0 set "daysPerMonth[102]=129"
      )
   )
   if %Y%%M:~1%%D:~1% gtr %endDate% goto waitEndQueries
   set /A active+=1
if %active% lss %maxProcs% goto nextQuery

ECHO/
ECHO Initial set of %maxProcs% queries started, there are pending queries

rem Cycle of: wait seconds, count active processes, start a new one
:waitQuery
   ECHO/
   ECHO Waiting for an active query to end, in order to start the next one
   ping -n %seconds% localhost > NUL
   set active=0
   for %%a in (*.flg) do set /A active+=1
   if %active% geq %maxProcs% goto waitQuery
   set /A query+=1
   echo %query%- %Y%%M:~1%%D:~1% Started @ %time% >> query.log
   echo X > %Y%%M:~1%%D:~1%.flg
   start /B cmd.exe /D /C decode.exe ^< ResourceTXT/itch-%Y%%M:~1%%D:~1%.txt ^| select.exe %S_opts% ^| bookgen.exe %B_opts% ^| dump.exe %D_opts% ^> Output/%Y%%M:~1%%D:~1%.txt ^& del %Y%%M:~1%%D:~1%.flg
   ECHO Query %query%- %Y%%M:~1%%D:~1% started
   set /A D+=1
   if %D% gtr !daysPerMonth[%M%]! (
      set /A D=101, M+=1
      if !M! gtr 112 (
         set /A M=101, Y+=1, leap=Y%%4
         if !leap! equ 0 set "daysPerMonth[102]=129"
      )
   )
if %Y%%M:~1%%D:~1% leq %endDate% goto waitQuery

echo/
echo All requested queries has been started

rem Wait for the rest of active processes to end
:waitEndQueries
ping -n %seconds% localhost > NUL
if exist *.flg goto waitEndQueries

rem Complete the whole process:
(
echo/
echo Queries from %startDate% to %endDate%
echo Total queries processed: %query%
echo Start time: %startTime%
echo End time:   %time%
) >> query.log

copy /b *.txt my_data.ok
del *.txt
ren my_data.ok my_data.txt