使用DOS批处理语法,我需要等到一个模式出现在控制台输出中,然后在此之后打印所有内容(或者至少在匹配后打印N行)。我怎样才能做到这一点? (像Unix中的grep + A)。我可以简单地做到这一点,以获得模式:
run_my_command | findstr "my_pattern"
但是看看findstr手册,似乎没有一个开关来打印所有东西(或模式之后的N行)。我不是DOS批次的专家,所以如果你有想法,请直接。
编辑:
这是我输出的最后一部分(即在这些行之前有很多行,但我感兴趣的是测试的结果,即“结果:”之后的所有内容都是粗体)
...
...
21:23:26.332 [Thread-4] DEBUG o.s.b.f.s.DisposableBeanAdapter - 在bean上调用destroy(),名称为'ehcache'
21:23:26.332 [Thread-4] INFO o.s.c.e.EhCacheManagerFactoryBean - 关闭EhCache CacheManager
21:23:26.332 [Thread-4] DEBUG net.sf.ehcache.CacheManager - CacheManager已经关闭
结果:测试错误:ReceiptsSearchRequestBuilderTest.testCreateSearchRequest_loadDate:97» IllegalArgument ReceiptLineControllerTest.testFind:26»NullPointer 测试运行:229,失败:0,错误:2,跳过:0
[INFO] ----------------------------------
[INFO]建立失败
[INFO] ----------------------------------
[INFO]总时间:23.213秒
[INFO]完成时间:2015-08-03T14:23:26-07:00
[INFO]最终记忆:19M / 453M
[INFO] -------------------------------
编辑:
这是我的脚本。当我没有重定向到%log%时,它只在我的模式之后打印文本,这就是我想要的。但是当我将其重定向到%log%时,日志文件包含所有文本(stderr也正确地转储为null)。
@echo OFF
SET MAVEN_PROFILE=ie
SET root_dir="%USERPROFILE%\Desktop\MyFolder"
SET log=%root_dir%/log.txt
powershell -c "$txt=(&mvn -P %MAVEN_PROFILE% -Dtest=LoginTest test > %log% 2> null) -join \"`r`n\"; $i=$txt.indexof('Results :'); if($i -ge 0) { $j=$txt.lastindexof(\"`n\",$i); write-host $txt.substring([math]::max(0,$j+1))}"
答案 0 :(得分:0)
你是什么意思模式出现?你想找到哪里?由于你想要打印N行或之后的所有内容,我假设您正在搜索文本文件中的单词而不是模式。
@echo off
set /p word = What word/pattern you are searching for? ^>
set bool = 0
for /f "tokens=*" %%a in (Text.txt) do (
if %%a == %word% set bool = 1
if %bool% == 1 echo %%a
)
此脚本仅在找到您要查找的单词后打印所有内容。
答案 1 :(得分:0)
当然,您需要执行通过管道连接的两个部件,就像您的示例一样。虽然可以在纯批处理中编写右侧管道进程,但批处理文件处理在从管道读取时会出现同步问题,因此我们需要使用不同的语言。
JScript是一种比Batch更强大的编程语言,可以在XP上的所有Windows版本中使用,并且很容易将Batch和JScript代码组合在同一个混合脚本中:
编辑:第一行中缺少@
。固定
@set @Batch=1 /*
@echo off
run_my_command | CScript //nologo //E:JScript "%~F0"
goto :EOF */
// JScript section
var lineFound = false, numOfLines = N;
while ( ! WScript.Stdin.AtEndOfStream ) {
line = WScript.Stdin.ReadLine();
if ( ! lineFound && line.indexOf("my_pattern") >= 0 ) lineFound = true;
if ( lineFound && numOfLines ) {
WScript.Stdout.WriteLine(line);
--numOfLines;
}
}
将以前的代码保存在扩展名为.bat的文件中;你需要在代码中调整一些细节。
答案 2 :(得分:0)
这里有一个使用powershell的单线程,您可以从批处理文件中运行,在120MB输出结束时需要10秒钟才能找到一个字符串:
powershell -c "$txt=(&your_console_app -with -arguments) -join \"`r`n\"; $i=$txt.indexof('string_to_search_for'); if($i -ge 0) { $j=$txt.lastindexof(\"`n\",$i); $txt.substring([math]::max(0,$j+1)) }"
your_console_app -with -arguments
和string_to_search_for
。如果那些包含双引号将它们转义为\"
。pause
,以便在需要时保持控制台窗口打开。使用实际命令行的示例,该命令行输出到重定向到文件的标准输出:
@echo OFF
SET MAVEN_PROFILE=ie
SET root_dir="%USERPROFILE%\Desktop\MyFolder"
SET log=%root_dir%/log.txt
powershell -c "$txt=(&mvn -P %MAVEN_PROFILE% -Dtest=LoginTest test 2>nul) -join \"`r`n\"; $i=$txt.indexof('Results :'); if($i -ge 0) { $j=$txt.lastindexof(\"`n\",$i); $txt.substring([math]::max(0,$j+1)) }" >results.txt
或者,您可以直接从powershell代码中写入文件:
powershell -c "$txt=(&mvn -P %MAVEN_PROFILE% -Dtest=LoginTest test 2>nul) -join \"`r`n\"; $i=$txt.indexof('Results :'); if($i -ge 0) { $j=$txt.lastindexof(\"`n\",$i); $txt.substring([math]::max(0,$j+1)) | out-file 'results.txt' }"
答案 3 :(得分:0)
这是与Aacini的答案类似的想法,除了它使用一个已经编写的混合JScript /批处理实用工具JREPL.BAT,它为批处理提供了复杂的正则表达式文本处理功能。 JREPL.BAT是纯脚本,可以在XP之后的任何Windows机器上本机运行。完整的文档嵌入在脚本中。
要跳过输出并使用以Results :
yourCommand | jrepl "^Results :[\s\S]*" "$0" /jmatch /m
仅打印以Results :
开头的行,加上接下来的4行(共5行)
yourCommand | jrepl "^Results :(.*\n){0,4}.*$" "$0" /jmatch /m
上述两个命令都使用/M
多行选项,这意味着必须将整个输出加载到内存中。在命令完成之前不会打印任何内容。如果输出是几千兆字节,或者如果它长时间运行,并且您希望尽快看到输出,这可能是一个问题。
使用更多代码和用户提供的JScript,可以独立处理和打印每一行 - 没有延迟,也没有大小限制:
从以Results :
yourCommand | jrepl "^Results :.*|^.*" "go=true;$0|go?$0:false" /jmatch /t "|" /jbeg "var go=false"
仅打印以Results :
开头的行,加上接下来的4行(总共5行)
yourCommand | jrepl "^Results :.*|^.*" "go=5;$0|(--go>0)?$0:false" /jmatch /t "|" /jbeg "var go=0"