在下面的代码中,我想要获取字符串的行号#34; AXX0000XXXA"从文件data.txt,然后逐行获取并打印target.txt文件,如果该行到达查找行之间没有我从文件temp.txt中添加另一行。代码工作正常,少了nos记录(用150行测试 - 文件大小100 kb),但当我处理50K记录(文件大小25MB)时,处理时间超过25分钟。请你帮助我如何在更短的时间内处理它们。
@echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set find_line=%%a)
set /a counter=0
for /f "usebackq delims=" %%b in (`"findstr /n ^^ C:\Users\23456\Desktop\data.txt"`) do (
set curr_line=%%b
set /a counter=!counter!+1
if !counter! equ !find_line! (
type temp.txt >> target.txt
)
call :print_line curr_line
)
endlocal
:print_line
setlocal enabledelayedexpansion
set line=!%1!
set line=!line:*:=!
echo !line!>>target.txt
endlocal
答案 0 :(得分:1)
您的代码使用三个本身很慢的批处理文件构造:call
命令,>>
追加重定向和setlocal/endlocal
,这些构造每个文件行执行一次!将子例程包含在原始代码中以避免call
和setlocal
命令会更快,echo !line!>>target.txt
命令意味着打开文件,搜索结尾,附加数据和关闭文件,因此使用此结构更快:(for ...) > target.txt
只打开文件一次。具有此类更改的代码示例在Compo的答案中。
这是解决此问题的另一种方法,当搜索行放置在文件的开头时,该方法可能会运行得更快:
@echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set /A find_line=%%a-1)
call :processFile < "C:\Users\23456\Desktop\data.txt" > target.txt
goto :EOF
:processFile
rem Duplicate the first %find_line%-1 lines
for /L %%i in (1,1,%find_line%) do (
set /P "line="
echo !line!
)
rem Insert the additional line
type temp.txt
rem Copy the rest of lines
findstr ^^
exit /B
答案 1 :(得分:0)
这应创建内容与target.txt
匹配的data.txt
,但在与搜索字符串tmp.txt
匹配的行的正上方AXX0000XXXA
取得的插入行除外。
@Echo Off
Set "fSrc=C:\Users\23456\Desktop\data.txt"
Set "iSrc=temp.txt"
Set "sStr=AXX0000XXXA"
Set "fDst=target.txt"
Set "iStr="
Set/P "iStr="<"%iSrc%" 2>Nul
If Not Defined iStr Exit/B
Set "nStr="
For /F "Delims=:" %%A In ('FindStr/N "%sStr%" "%fSrc%" 2^>Nul') Do Set "nStr=%%A"
If Not Defined nStr Exit/B
( For /F "Tokens=1*Delims=:" %%A In ('FindStr/N "^" "%fSrc%"') Do (
If "%%A"=="%nStr%" Echo %iStr%
Echo %%B))>"%fDst%"
我让您可以轻松更改可变数据,您只需更改第3-6行。
我认为这是你的意图,你的问题不明确,如果我假设错误,请接受我的道歉。