我有一个如下所示的日志文件:
Beginning difffull backup for database Managed_Metadata_Service, 3 of 149.
Full: 0 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 4 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Backup of Managed_Metadata_Service failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Beginning difffull backup for database model, 4 of 149.
Full: 0 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 2 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 4 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Backup of model failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Beginning difffull backup for database msdb, 5 of 149.
Full: 0 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 4 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Backup of msdb failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Beginning difffull backup for database Search_Service_Application_AnalyticsReportingStoreDB, 6 of 149.
Full: 0 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Full: 4 Read: 6144 Written: 0 Rate: 0.00 Kb/Sec
Backup of Search_Service_Application_AnalyticsReportingStoreDB failed.
ANS0238E (RC2041) The sequence of calls is invalid.
如何找到failed
的所有匹配项,然后打印带有此单词和下一行的行直到消息结束,这意味着直到段落末尾或文件末尾的下一个点?
结果如下:
Backup of Managed_Metadata_Service failed.
ANS0238E (RC2041) The sequence of calls is invalid.
.
.
Search_Service_Application_AnalyticsReportingStoreDB failed.
ANS0238E (RC2041) The sequence of calls is invalid.
对于failed
字的所有行。
这是我到目前为止的代码:
@echo off
setlocal EnableDelayedExpansion
set numbers=
for /F "delims=^" %%a in ('findstr /I /N /C:"failed" Backup_DIFF_2017-12-14.log') do (
set /A sameline=%%a, after=%%a+1
set "numbers=!numbers!!sameline!: !after!: "
)
rem Search for the lines
(
for /F "tokens=* delims=^ %%a in ('findstr /N "^" Backup_DIFF_2017-12-14.log ^| findstr /B "%numbers%"') do echo %%b
) > result.txt
答案 0 :(得分:1)
Stephan对此日志文件示例所建议的简单解决方案是:
@%SystemRoot%\System32\findstr.exe "failed\.$ ^ANS" "Backup_DIFF_2017-12-14.log"
此单个命令行输出:
Backup of Managed_Metadata_Service failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Backup of model failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Backup of msdb failed.
ANS0238E (RC2041) The sequence of calls is invalid.
Backup of Search_Service_Application_AnalyticsReportingStoreDB failed.
ANS0238E (RC2041) The sequence of calls is invalid.
FINDSTR 搜索以failed.
结尾的行或以ANS
开头的行并输出这些行。点必须位于正则表达式搜索字符串中,并使用反斜杠将其解释为文字字符。 FINDSTR 不支持多行正则表达式搜索。
备用 FINDSTR 命令行还在每行 OR 上运行两个正则表达式搜索:
@%SystemRoot%\System32\findstr.exe /R /C:failed\.$ /C:^ANS "Backup_DIFF_2017-12-14.log"
更复杂的解决方案是使用此批处理代码:
@echo off
if not exist "Backup_DIFF_2017-12-14.log" goto :EOF
setlocal EnableExtensions EnableDelayedExpansion
set "PrintLines="
for /F "tokens=1* delims=:" %%I in ('%SystemRoot%\System32\findstr.exe /N /R "^" "Backup_DIFF_2017-12-14.log"') do (
if "%%J" == "" (
set "PrintLines="
) else (
set "Line=%%J"
if not "!Line:failed=!" == "!Line!" set "PrintLines=1"
)
if defined PrintLines echo %%J
)
endlocal
输出相同。此代码输出包含任何不区分大小写failed
的任何行,并将此行以及所有其他行输出到文件中的下一个空行。空行不包含任何字符,甚至不包含空格或水平制表符。
此代码存在两个问题:
delims=:
删除,需要将每行输出 FINDSTR 与行号分开,冒号和行本身。
FINDSTR 用于处理 FOR 甚至是空行,因为在搜索文件时运行 FINDSTR 后,包含空行的所有行都以行号和冒号开头行的开头导致每一行都出现正匹配。set "Line=%%J"
替换为文件中的行后,在命令行%%J
上应用了启用的延迟环境变量扩展。另一个不是100%完美的解决方案:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "PrintLines="
for /F "usebackq delims=" %%I in ("Backup_DIFF_2017-12-14.log") do (
set "Line=%%I"
if "!Line:~0,9!" == "Beginning" (
set "PrintLines="
) else (
if not "!Line:failed=!" == "!Line!" set "PrintLines=1"
)
if defined PrintLines echo %%I
)
endlocal
与第二个解决方案相比,此批处理代码将行开头的区分大小写的Beginning
解释为新段而不是空行。因此,命令 FOR 可以直接处理文件而忽略空行。
但是这个解决方案还有两个问题:
;
是未明确设置为其他字符的选项eol
的默认值。这个问题可以通过在日志文件的一行开头用一个绝对不存在的字符指定eol=
来解决。set "Line=%%I"
替换为文件中的行后,在命令行%%I
上应用了启用的延迟环境变量扩展。此解决方案预计以Beginning
开头的行在该行的任何位置都不包含单词failed
。
要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
set /?
setlocal /?