在文件名中加入MD5校验和

3

在一个目录中有很多文件,它们的名字分别为1.txt、2.txt、3.txt直到n.txt。我需要将它们全部重命名为它们的md5值。

我尝试过,但失败了。

for %f in (*.txt) do certutil -hashfile "%f" MD5 | findstr /C:2
3个回答

2
如果您确实需要从命令行执行此操作(根据您问题中的语法),则只需使用额外的 for /f 处理每个文件执行 certutil 命令的输出即可。
for %a in (*.txt) do @for /f "skip=1 tokens=1,* delims=:" %b in ('certutil -hashfile "%a" MD5') do @if "%c"=="" @echo ren "%a" "%b%~xa"
for /f使用skip子句来避免在certutil输出中的第一行(文件名)和冒号作为分隔符来拆分行以处理不需要的输出消息(以CertUtil:开头)。这样,如果该行包含冒号(不需要的行),它将被拆分为两个部分(tokens=1,*),将左标记存储在%b中,右标记存储在%c中。如果%c有任何内容,则这不是包含哈希的行。如果%c为空,则这是具有哈希的行,我们将重命名文件。注意:ren命令只会回显到控制台。如果输出看起来正确,请删除echo命令。如果文件无法读取(锁定或为空),则certutil仅输出错误行,因此不会有任何哈希,并且所有行都将被丢弃而不执行重命名操作。无论如何,从命令行执行此操作容易出错。如果可以,请像Hackoo建议的那样使用批处理文件。
@echo off
    setlocal enableextensions disabledelayedexpansion

    for /f "tokens=1,* delims=:" %%a in ('
        cmd /q /c "for %%f in (*.txt) do certutil -hashfile "%%f" MD5&&(echo file:%%f)"
        ^| findstr /v /b /i /c:"MD5" /c:"Cert" 
    ') do (
        if "%%a"=="file" (
            set "file=%%b"
            set "extension=%%~xb"
            setlocal enabledelayedexpansion
                echo ren "!file!" "!md5: =!!extension!"
            endlocal
            set "md5="
        ) else (
            set "md5=%%a"
        )
    )

编辑:根据评论中sst指出的更正,将其包含在批处理代码中。


批处理运行后,脚本的名称已更改,但文件扩展名丢失。就像“e2cfe4cd8e52eed3e602b6730df29d4e”一样。没有文件扩展名。 - Gamarlinsky
@AligamarliNamazov 你至少测试了我的批处理吗? - Hackoo
@AligamarliNamazov,答案已更新。你只需要将ren“%a”%b更改为ren“%a”“%b%〜xa”(保留文件扩展名被%a引用)或者如果你只处理.txt文件,则可以简单地使用ren“%a”%b.txt - MC ND
2
@MCND,在某些Windows版本中,哈希算法必须以大写形式传递,否则cerutil将失败。这在我的Windows 7上绝对是这种情况,在我的Windows 10上,certutil接受小写、大写和混合大小写。我找不到微软关于这种行为的任何官方声明。此外,从哈希字符串中删除空格似乎是一个好主意,因为不同的Windows版本之间存在不同的输出格式。例如:e2 cf e4 cd ... vs e2cfe4cd... - sst
1
@sst,谢谢,你是正确的。由于糟糕的内存和手边只有Windows 10,才会出现这种情况。 - MC ND

0
你可以尝试类似这样的批处理脚本,只需将其保存为Rename2MD5.bat并放在存储文本文件的同一目录中,然后双击执行它。如果一切正常,您可以在Ren命令之前删除echo命令。
@echo off
Color 0A 
Title Rename Files to MD5 Hashes
echo(
SetLocal EnableDelayedExpansion
for %%a in (*.txt) do (
     for /f "skip=1 delims=" %%H in ('CertUtil -hashfile "%%a" MD5 ^| findstr /i /v "CertUtil"') do ( set H=%%H)
        echo "%%a" = "!H!.txt"
        echo Ren "%%a" "!H!.txt"
)
EndLocal
Pause & Exit

0
为了确保我重新命名的`.txt`文件不会在初始的`For`循环中被循环处理,而且由于MD5的结果可能是一组由空格分隔的两个字符字符串,我可能会考虑使用批处理文件来实现这个功能。
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

For /F "Delims==" %%A In ('Set _[ 2^>Nul') Do Set "%%A="

For /F "Tokens=1* Delims=]" %%A In ('Where .:*.txt 2^>Nul^|Find /N /V ""') Do (
    For /F "Delims=" %%C In ('CertUtil -HashFile "%%B" MD5 2^>Nul^|Find /V ":"'
    ) Do (Set "_=%%C" & Call Set "_%%A]=Ren "%%B" "%%_: =%%%%~xB""))

For /F "Tokens=1* Delims==" %%A In ('Set _[ 2^>Nul') Do %%B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接