BATCH-在没有临时文件的情况下,将命令输出的特定行写入变量



certutil hash.cmd的代码 :

@echo off
certutil -hashfile "%~dpnx0" md5
pause>nul

我想把第二行的散列值保存在一个变量中。CMD输出:

MD5 hash from C:UsersZerTerODesktopcertutil-hash.cmd:
9913d66d0b741494962e94ff540a8147
CertUtil: -hashfile command executed successfully.

在我看来,唯一的解决方案是这样的:

@echo off
cls
call:hashfile
set "md5=%md5: =%"
echo.%md5%
pause>nul
exit
:hashfile
for /f "skip=1 tokens=1 delims=" %%a in ('certutil -hashfile "%~dpnx0" md5') do (set "md5=%%a" & goto:eof)

有没有更优雅的解决方案?

我只需要这样做,因为Windows7和Windows8在值之间写空格:

set "md5=%md5: =%"

提前感谢。。。

ZerTerO

对于使用HashAlgorithm参数的CertUtil版本,(请参阅我的评论(,您可以更好地处理循环,如下所示:

Set "md5="
For /F Delims^= %%G In ('CertUtil -HashFile "%~f0" MD5^|FindStr /VRC:"[^a-f 0-9]"')Do Set "md5=%%G"

或者更像这样:

Set "md5="
For /F Delims^= %%G In ('^""%__APPDIR__%certutil.exe" -HashFile "%~f0" MD5^|"%__APPDIR__%findstr.exe" /VRC:"[^a-f 0-9]"^"')Do @Set "md5=%%G"

使用findstr排除任何包含非字母字符abcdef的字符的行;数字字符0123456789;或者一个空格字符,在我看来,比跳过第一行,然后在处理完第二行后跳出循环更优雅。

至于结果变量,我不确定,在这种情况下,我是否会使用set "md5=%md5: =%"来专门删除可能的空格,我只使用echo.%md5: =%。然而,如果我在剩下的脚本中经常使用结果变量,我会在标记的部分中执行该任务:

@Echo Off
SetLocal EnableExtensions
ClS
Set "algo=MD5"
Call :HashFile "%~f0" %algo%
Echo(%hash%
Pause 1> NUL
GoTo :EOF
:HashFile
Set "hash="
For /F Delims^= %%G In ('^""%__APPDIR__%certutil.exe" -HashFile %1 %2 2^> NUL ^
 ^| "%__APPDIR__%findstr.exe" /V /R /C:"[^a-f 0-9]"^"') Do Set "hash=%%G"
If Not "%hash: =%" == "%hash%" Set "hash=%hash: =%"
Exit /B

理想情况下,5行应该是例程的一部分,该例程确定操作系统上的certutil版本是否支持两个参数。如果不这样做,则该行将读取Set "algo="。您还会注意到,我已将您的硬编码文件名移出循环,并将其用作Call命令的第一个输入参数。这将使您的脚本更加模块化,并且IMO更加优雅。我还认为,在要求什么都不替换之前,检查%hash%是否包含空格更为优雅优雅与效率不一定相同

相关内容

  • 没有找到相关文章

最新更新