[英]How to iterate through FOR IN outputs with IF statements in Windows Batch?
我有一个文件目录,一个HashControlFile.txt
,其中包含从目录中的文件计算出的 SHA256 总和,并且需要以一种从 Windows 中的CertUtil
实用程序计算和格式化 output 的方式遍历这些文件,并在两者之间进行检查目录文件和 HashControlFile,并提供一个框架来执行附加操作,无论是否在它们之间找到匹配项。
HashControlFile.txt
仅包含 SHA256sum 条目,每行一个新条目,例如:
181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b
对于内容仅为123
的文件。
我已经有了这个难题的两个要素。 要循环遍历任何生成 SHA256sum 的目录,下面的生成方式会对其进行格式化,以防止 Windows 上不同版本的CertUtil.exe
之间可能发生的十六进制配对:
for %%i in (\\FileDirectory\*) do (
@For /F "Delims=" %%G In ('%SystemRoot%\System32\certutil.exe -HashFile "%%i" SHA256 2^>NUL ^| %SystemRoot%\System32\find.exe /V ":"') Do @Set "hash=%%G" & SetLocal EnableDelayedExpansion & For %%H In ("!hash: =!") Do @EndLocal & Echo(%%~H) >> \\OtherDirectory\HashControlFile.txt
)
此外,要遍历目录并比较文件和 HashControlFile 之间的内容,我有以下内容:
FOR /f "delims=" %%b IN (\\FileDirectory\*) DO (
FOR /f %%y IN (####Produce FORMATTED SHA256SUM HERE####) do (
findstr /x "%%y" \\OtherDirectory\HashControlFile.txt > NUL
IF ERRORLEVEL 1 (
ECHO "%%b" NOT found
) ELSE (
ECHO "%%b" found
)
)
)
我的困难在于在第二个元素中使用上述元素来循环使用格式化的 CertUtil output。任何帮助将不胜感激
在仅包含 SHA256 hash 值的文件中的目录中的每个文件的 SHA256 hash 查找可以使用以下批处理文件完成:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Directory=\\ServerName\ShareName\FilesDirectory"
set "HashFile=\\ServerName\ShareName\OtherDirectory\HashControlFile.txt"
if not exist "%HashFile%" echo ERROR: Missing file: "%HashFile%"& goto EndBatch
for %%G in ("%Directory%\*") do if /I not "%%G" == "%HashFile%" if not "%%G" == "%~f0" (
set "FileName=%%~nxG"
for /F "delims=" %%H In ('%SystemRoot%\System32\certutil.exe -HashFile "%%G" SHA256 2^>NUL ^| %SystemRoot%\System32\find.exe /V ":"') do (
setlocal EnableDelayedExpansion
set "HashValue=%%H"
%SystemRoot%\System32\findstr.exe /L /X /C:"!HashValue: =!" "!HashFile!" >nul
if not errorlevel 1 (
echo FOUND: "!FileName!"
) else (
echo MISSING: "!FileName!"
)
endlocal
)
)
:EndBatch
endlocal
环境变量Directory
定义为包含文件的目录,应确定其 SHA256 hash 值并在具有 hash 值的文件中查找。
环境变量HashFile
使用包含所有 SHA256 hash 值的 ASCII/ANSI 编码文本文件的完全限定文件名定义。
然后检查具有 hash 值的文件是否存在。 错误消息为 output,如果指定的 hash 列表文件根本不存在,则不会执行任何其他操作。 另请参阅使用 Windows 批处理文件的单行多命令,以了解无条件命令运算符&
在命令行中与第一个IF条件一起使用的说明。
最外层的FOR循环处理指定目录下的所有非隐藏文件。
具有不区分大小写的字符串比较的第二个IF条件用于忽略具有 hash 值的文件,前提是该文件与要处理的文件位于同一目录中,而上述代码中指定的路径并非如此,而是在一般可能。
具有区分大小写字符串比较的第三个IF条件用于如果当前处理的批处理文件在要处理的文件目录中则忽略该批处理文件。
带文件扩展名但不带当前文件路径的文件名被分配给环境变量FileName
。 执行此命令行和下一个命令行时禁用延迟变量扩展,导致整个批处理文件也适用于完全限定文件名中带有一个或多个感叹号的文件。
内部FOR循环在后台运行一个带有%ComSpec% /c
的命令进程,并且'
中指定的命令行附加为附加 arguments。
阅读有关使用命令重定向运算符的 Microsoft 文档,了解2>NUL
和|
的解释。 . 重定向运算符>
和|
当 Windows 命令解释器在执行命令FOR之前处理此命令行时,必须在FOR命令行上使用脱字符^
进行转义,该命令使用在后台启动的单独命令进程执行嵌入式命令行。
文件的 SHA256 hash 值分配给循环变量H
,其格式为:
18 12 10 f8 f9 c7 79 c2 6d a1 d9 b2 07 5b de 01 27 30 2e e0 e3 fc a3 8c 9a 83 f5 b1 dd 8e 5d 3b
必须删除空格才能获得 SHA256 hash 值,以便在包含所有 hash 值的文件中查找。
在将带有空格的 hash 值分配给名称为HashValue
的环境变量之前,现在启用了延迟变量扩展。
接下来执行FINDSTR在文件中搜索所有 hash 值字面和区分大小写的行,该行与当前 hash 值完全匹配,使用延迟扩展变量引用删除所有空格,并用空字符串替换每个空格字符,即从 hash 值中删除所有空格字符。 如果在 hast 列表文件中完全找到 hash 值,则找到的行没有意义,这就是将 FINDSTR 的output重定向到设备NUL以抑制它的原因。
如果没有匹配项,则FINDSTR以退出代码1
退出,如果至少有一个匹配项,则以退出代码0
退出。 退出代码由cmd.exe
分配给其内部动态变量ERRORLEVEL
。 此退出代码被评估为小于 1,这意味着 0 到 output FOUND:
或MISSING:
具有当前文件名的消息。
然后使用再次禁用的延迟变量扩展恢复先前的执行环境。 阅读此答案以了解有关命令SETLOCAL和ENDLOCAL的详细信息,因为cmd.exe
在后台对内部FOR循环的每次迭代所做的工作比仅更改延迟变量扩展的状态要多得多。
要了解使用的命令及其工作原理,请打开命令提示符window,在那里执行以下命令,并仔细完整地阅读每个命令显示的帮助页面。
certutil /?
或certutil -?
echo /?
endlocal /?
find /?
findstr /?
for /?
goto /?
if /?
set /?
setlocal /?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.