Batch file 在许多大文本文件上运行多个管道命令的快速方法
我在文本文件中存储了大量数据(每个文件中有一天的数据,最大大小约为1.5gb)。它们是数据源,因此必须处理为人类可读的格式,这是由几个C程序(不是我写的)完成的 通过f.ex运行命令,我获得了一天的特定数据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
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