如果在几行中包含相同的字符串,如何在日志中只列出一行?

时间:2016-12-09 08:19:48

标签: windows batch-file findstr

我有一个.log文件作为 sfv 检查的结果 它主要包含OK,但有些Failed和一些Not Found

我用过

findstr /v "OK" "sfv.Log" > "Sfv.Replace.Log"

只能获取错误的文件/文件夹。

但它仍然在同一文件夹中留下了大量损坏的文件,因此日志仍然很长。

是否有一种简单的方法(批处理)我每个文件夹只能获得一行?

例如我想要日志行

NOT FOUND    *****        CD8542\EN\contents\cnt\FSE14_15_07.swf
NOT FOUND    *****        CD8542\EN\contents\cnt\FSE19_05_01.flv
NOT FOUND    *****        CD8542\EN\contents\cnt\FSE19_05_02.flv
NOT FOUND    *****        CD8542\EN\contents\cnt\FSE19_06_01.flv
NOT FOUND    *****        CD8542\EN\contents\cnt\FSE19_06_05.flv
NOT FOUND    *****        CD8542\EN\contents\cnt\FSE19_06_06.flv
NOT FOUND    *****        CD8542\EN\contents\cnt\FSE19_08_02.flv
NOT FOUND    *****        CD8542\EN\contents\cnt\FSE19_08_03.flv
NOT FOUND    *****        CD8539\Course01\Lesson01\Exi_04\snd\NO.18.mp3
NOT FOUND    *****        CD8539\Course01\Lesson01\Exi_04\snd\NO.180.mp3
NOT FOUND    *****        CD8539\Course01\Lesson01\Exi_04\snd\NO.181.mp3
NOT FOUND    *****        CD8539\Course01\Lesson01\Exi_04\snd\NO.182.mp3
NOT FOUND    *****        CD8539\Course01\Lesson01\Exi_04\snd\NO.183.mp3
NOT FOUND    *****        CD8539\Course01\Lesson01\Exi_04\snd\NO.184.mp3
FAILED       CRC32        CD0165\Course01\Lesson01\alcap_4\5\q3.xml
FAILED       CRC32        CD0165\Course01\Lesson01\alcap_4\5\q4.xml
FAILED       CRC32        CD0165\Course01\Lesson01\alcap_4\5\q5.xml
FAILED       CRC32        CD0165\Course01\Lesson01\alcap_4\5\q6.xml
FAILED       CRC32        CD0165\Course01\Lesson01\alcap_4\5\q7.xml
FAILED       CRC32        CD0165\Course01\Lesson01\alcap_4\5\q8.xml

输出

NOT FOUND    *****        CD8542\EN\contents\cnt\FSE14_15_07.swf
NOT FOUND    *****        CD8539\Course01\Lesson01\Exi_04\snd\NO.18.mp3
FAILED       CRC32        CD0165\Course01\Lesson01\alcap_4\5\q3.xml

通过这种方式,我可以更轻松地查看我可以替换的整个特定文件夹。

1 个答案:

答案 0 :(得分:0)

此过滤任务可以通过以下批处理代码实现:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
del "Sfv_Replace.log" 2>nul
for /F "delims=" %%I in ('%SystemRoot%\System32\findstr.exe /V "OK" "sfv.log" 2^>nul') do (
    set "LogLine=%%I"
    set "FileNameWithPath=!LogLine:*CD=CD!"
    for %%J in ("!FileNameWithPath!") do set "FilePath=!FileNameWithPath:\%%~nxJ=!
    set "VariableName=Folder#!FilePath:\=_!
    if not defined !VariableName! (
        echo !LogLine!>>"Sfv_Replace.log"
        set "!VariableName!=1"
    )
)
endlocal

如果日志文件Sfv_Replace.log仍然存在,则会先删除日志文件sfv.log

接下来,控制台应用程序 FINDSTR 在文件OK上执行,该文件输出所有行,其中包含字符串LogLine区分大小写的区域CD线。

这些行由外部 FOR 循环处理,它首先将整个当前行分配给环境变量FileNameWithPath

( ...每个目录路径的开头...的所有内容都从日志文件的行中删除,以获取文件的名称,并使用分配给环境变量)的相对路径在命令块中定义/修改环境变量时,根据需要延迟扩展,以FileNameWithPath开头,以匹配CD8542\EN\contents\cnt\FSE14_15_07.swf CD8542\EN\contents\cnt\FSE19_05_01.flv CD8542\EN\contents\cnt\FSE19_05_02.flv CD8542\EN\contents\cnt\FSE19_06_01.flv CD8542\EN\contents\cnt\FSE19_06_05.flv CD8542\EN\contents\cnt\FSE19_06_06.flv CD8542\EN\contents\cnt\FSE19_08_02.flv CD8542\EN\contents\cnt\FSE19_08_03.flv CD8539\Course01\Lesson01\Exi_04\snd\NO.18.mp3 CD8539\Course01\Lesson01\Exi_04\snd\NO.180.mp3 CD8539\Course01\Lesson01\Exi_04\snd\NO.181.mp3 CD8539\Course01\Lesson01\Exi_04\snd\NO.182.mp3 CD8539\Course01\Lesson01\Exi_04\snd\NO.183.mp3 CD8539\Course01\Lesson01\Exi_04\snd\NO.184.mp3 CD0165\Course01\Lesson01\alcap_4\5\q3.xml CD0165\Course01\Lesson01\alcap_4\5\q4.xml CD0165\Course01\Lesson01\alcap_4\5\q5.xml CD0165\Course01\Lesson01\alcap_4\5\q6.xml CD0165\Course01\Lesson01\alcap_4\5\q7.xml CD0165\Course01\Lesson01\alcap_4\5\q8.xml 结束,并在同一命令块中引用该值。

在示例行上运行批处理文件时FilePath的所有值都是:

FilePath

内部 FOR 循环用于从具有相对路径的文件名获取文件名和文件扩展名,这些文件名和文件扩展名从文件名中删除,其中包含路径以获取存储的相对目录路径在环境变量 CD8542\EN\contents\cnt CD8542\EN\contents\cnt CD8542\EN\contents\cnt CD8542\EN\contents\cnt CD8542\EN\contents\cnt CD8542\EN\contents\cnt CD8542\EN\contents\cnt CD8542\EN\contents\cnt CD8539\Course01\Lesson01\Exi_04\snd CD8539\Course01\Lesson01\Exi_04\snd CD8539\Course01\Lesson01\Exi_04\snd CD8539\Course01\Lesson01\Exi_04\snd CD8539\Course01\Lesson01\Exi_04\snd CD8539\Course01\Lesson01\Exi_04\snd CD0165\Course01\Lesson01\alcap_4\5 CD0165\Course01\Lesson01\alcap_4\5 CD0165\Course01\Lesson01\alcap_4\5 CD0165\Course01\Lesson01\alcap_4\5 CD0165\Course01\Lesson01\alcap_4\5 CD0165\Course01\Lesson01\alcap_4\5

在示例行上运行批处理文件时Folder#的所有值都是:

VariableName

相对目录路径中的所有反斜杠都被下划线替换,并在开始时插入Folder#CD8542_EN_contents_cnt Folder#CD8542_EN_contents_cnt Folder#CD8542_EN_contents_cnt Folder#CD8542_EN_contents_cnt Folder#CD8542_EN_contents_cnt Folder#CD8542_EN_contents_cnt Folder#CD8542_EN_contents_cnt Folder#CD8542_EN_contents_cnt Folder#CD8539_Course01_Lesson01_Exi_04_snd Folder#CD8539_Course01_Lesson01_Exi_04_snd Folder#CD8539_Course01_Lesson01_Exi_04_snd Folder#CD8539_Course01_Lesson01_Exi_04_snd Folder#CD8539_Course01_Lesson01_Exi_04_snd Folder#CD8539_Course01_Lesson01_Exi_04_snd Folder#CD0165_Course01_Lesson01_alcap_4_5 Folder#CD0165_Course01_Lesson01_alcap_4_5 Folder#CD0165_Course01_Lesson01_alcap_4_5 Folder#CD0165_Course01_Lesson01_alcap_4_5 Folder#CD0165_Course01_Lesson01_alcap_4_5 Folder#CD0165_Course01_Lesson01_alcap_4_5 来构建环境变量名称。

在示例行上运行批处理文件时Sfv_Replace.log的所有值都是:

1

如果已经定义了具有该名称的环境变量,则最后检查当前环境变量名称。如果是这种情况,则忽略日志文件中的行。否则,日志文件中的行将通过重定向输出到附加它的日志文件Sfv_Replace.log中,并使用值NOT FOUND ***** CD8542\EN\contents\cnt\FSE14_15_07.swf NOT FOUND ***** CD8539\Course01\Lesson01\Exi_04\snd\NO.18.mp3 FAILED CRC32 CD0165\Course01\Lesson01\alcap_4\5\q3.xml 定义环境变量。

所以最后文件del /?仅包含示例行:

echo /?

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • endlocal /?
  • for /?
  • if /?
  • set /?
  • setlocal /?
  • 2^>nul
  • >

另请参阅Microsoft文章Using command redirection operators

^上,使用插入符sfv.log对角括号(prev, current) => (prev.id > current.id ? prev.id : current.id) 进行转义,以解析将 FOR 命令行解析为文字字符,然后执行 FINDSTR 作为重定向运算符,将 FINDSTR 的错误消息输出重定向到处理 STDERR 到设备 NUL 以禁止它如果批处理文件没有{{1}}。