如何使用 7z 解压文件并且不替换具有相同名称但不同哈希值的文件?

如何使用 7z 解压文件并且不替换具有相同名称但不同哈希值的文件?

我如何告诉 7z 提取目录中的所有文件,告诉它不要替换具有相同名称但不同哈希值的文件?最好告诉它提取文件并将其重命名为其哈希值?

例如,假设我解压了两个 zip 文件,它们都有 x.dll,但哈希值不同(版本不同)。我想保留这两个文件,但如果它们是相同的版本(相同的哈希值),那么只保留一个。最好将解压的文件重命名为其哈希值,该怎么做?

现在我正在以这种方式提取:

 7z -y -aot -p"pass"  x "*.*"

(并非所有文件都包含密码,但如果包含,则密码相同,因此如果我做错了请纠正我)

为了提供背景信息,我有大量安装程序文件(.msi 或 .exe 文件,其中包含大量 exe 文件),我需要提取其中所有唯一的可执行文件

现在我正在使用 7z 的 Linux 版本,但我也可以使用 Windows 版本(在 VM 内)

答案1

所以,这是我的\Test Folder\*.*

I:\> tree /f /a
Folder PATH listing for volume 2ndHD
Volume serial number is FACF-B9ED
I:.
\---Test Folder
        extract n file 001.exe
        extract n file 002.msi
        extract y file 001.msi
        extract y file 002.exe
        extract y file 003.exe
        extract y file 003.msi
        file non exe msi.dat
        file non exe msi.log

这些是我的文件 [ ] 的 CRC,.exe | .msi存在于我的Folder Test\*.*

I:\> @echo\File CRC:     File Size:  File Names exe^|msi & @"C:\Program Files\7-Zip\7z.exe" h "I:\Test Folder\*.*"|%__AppDir__%FindSTR.exe /ei "\.exe \.msi"
 7z CRC:     Size .7z:  file .7z name exe|msi:
4F993E11         19320  extract n file 001.exe
93922786           230  extract n file 002.msi
754077D4          2018  extract y file 001.msi
324BD0AB          2112  extract y file 002.exe
CA78246F          2098  extract y file 003.exe
26176047          9164  extract y file 003.msi
  • 观察:对于输出7z h命令使用并经过 过滤Findstr,大小是一次性的,但在获取 CRC 和名称时,我们可以在另一个循环中使用它来查找该 CRC,并在另一个与 中的项目匹配时提取相关文件Test Folder
variable      ==> %%~i
tokens^=1     ==> 754077D4

variable                      ==> %%~j
tokens^= 2                    ==> 2018

variable                                  ==> %%~k
tokens^=  *                               ==> extract y file 001.msi

tokens^=1-2*  ==> 754077D4          2018      extract y file 001.msi 

这些是列出我的 7z 文件并进行过滤的结果,以便我通过以下方式在输出中获得 CRC 字符串FindSTR

I:\> "C:\Program Files\7-Zip\7z.exe" l -slt "H:\Q1634964.7z" -p"123456"|%__AppDir__%FindSTR.exe /bi "CRC.=...*"
CRC = B3871A85
CRC = 754077D4
CRC = 26176047
CRC = 7499157E
CRC = CA78246F
CRC = 324BD0AB

使用循环,我可以从文件中的每个文件中For /F获取 CRC 字符串".exe | .msi".7z,并使用另一个For /F在 oputput 中查找与我的本地文件\loop 匹配的字符串 CRC\Folder Test\

for /f useback^tokens^=1-2* %%i in (`"7z.exe h "I:\Test Folder\*.*"|FindSTR /ei "\.exe \.msi"" 
`)do for /f useback^tokens^=2delims^=^= %%I in (`"7z.exe l -slt "H:\Q1634964.7z" -p"123456"|FindSTR /bi "CRC"|FindSTR.exe /c:"%%~i""

使用循环,我可以从文件中For /F获取 CRC [ ] 字符串%%~iH: \Q1634964.7z,并附加For /F循环使用在第一个循环中获得的 CRC,来获取 CRC 和%%~k发生这种情况时文件的名称[ ],您可以轻松提取 CRC 匹配的文件,并且所有内容一起将是......

  • 在您的命令行中:
@pushd %__AppDir__% && @(for /f useback^tokens^=1-2* %i in (`""C:\Program Files\7-Zip\7z.exe" h "I:\Test Folder\*.*"|@FindSTR.exe /ei "\.exe \.msi""`)do @for /f useback^tokens^=2delims^=^= %I in (`""C:\Program Files\7-Zip\7z.exe" l -slt "H:\Q1634964.7z" -p"123456"|FindSTR.exe /bi "CRC"|FindSTR.exe /c:"%~i""`)do @set/p "'= 7z CRC: %~i | File CRC: %~I | Results: %~k | Status: "<nul & "C:\Program Files\7-Zip\7z.exe" e "H:\Q1634964.7z" -y o "%temp%\%~k" -r -p"123456"|Findstr.exe "Ok ERROR") & @popd
  • 在你的 bat 文件中:
@echo off 

pushd %__AppDir__% 
Setlocal EnabledelayeDexpansion
set "_7z=C:\Program Files\7-Zip\7z.exe" 

for /f useback^tokens^=1-2* %%i in (`""!_7z!" h "I:\Test Folder\*.*"|@FindSTR.exe /ei "\.exe \.msi""
     `)do for /f useback^tokens^=2delims^=^= %%I in (`""!_7z!" l -slt "H:\Q1634964.7z" -p"123456"|FindSTR.exe /bi "CRC"|FindSTR.exe /c:"%%~i""
     `)do set/p "'= 7z CRC: %%~i | File CRC: %%~I | Results: %%~k | Status: "<nul & "!_7z!" e "H:\Q1634964.7z" -y o "%temp%\%%~k" -r -p"123456"|Findstr.exe "Ok ERROR"
     
popd & endlocal & goto :eOf
  • 结果:
7z CRC: 754077D4 | File CRC:  754077D4 | Results: extract y file 001.msi | Status: Everything is Ok
7z CRC: 324BD0AB | File CRC:  324BD0AB | Results: extract y file 002.exe | Status: Everything is Ok
7z CRC: CA78246F | File CRC:  CA78246F | Results: extract y file 003.exe | Status: Everything is Ok
7z CRC: 26176047 | File CRC:  26176047 | Results: extract y file 003.msi | Status: Everything is Ok

如果不需要额外的状态输出:

  • 在您的命令行中:
@pushd %__AppDir__% && @(for /f useback^tokens^=1-2* %i in (`""C:\Program Files\7-Zip\7z.exe" h "I:\Test Folder\*.*"|@FindSTR.exe /ei "\.exe \.msi""`)do @for /f useback^tokens^=2delims^=^= %I in (`""C:\Program Files\7-Zip\7z.exe" l -slt "H:\Q1634964.7z" -p"123456"|FindSTR.exe /bi "CRC"|FindSTR.exe /c:"%~i""`)do @"C:\Program Files\7-Zip\7z.exe" e "H:\Q1634964.7z" -y o "%temp%\%~k" -r -p"123456") & @popd
  • 在您的批处理文件中:
@echo off 

pushd %__AppDir__% 
Setlocal EnabledelayeDexpansion
set "_7z=C:\Program Files\7-Zip\7z.exe" 

for /f useback^tokens^=1-2* %%i in (`""!_7z!" h "I:\Test Folder\*.*"|@FindSTR.exe /ei "\.exe \.msi""`)do for /f useback^tokens^=2delims^=^= %%I in (`
""!_7z!" l -slt "H:\Q1634964.7z" -p"123456"|FindSTR.exe /bi "CRC"|FindSTR.exe /c:"%%~i""`)do "!_7z!" e "H:\Q1634964.7z" -y o "%temp%\%%~k" -r -p"123456"|Findstr.exe "Ok ERROR"
     
popd & endlocal & goto :eOf

要重命名文件,我假设您想要/需要的是哈希("%%~i %%~k"),导致"Hash Name.eXtension"==>"CA78246F extract y file 002.exe"

  • 在您的命令行中:
@pushd %__AppDir__% && @(for /f useback^tokens^=1-2* %i in (`"@"C:\Program Files\7-Zip\7z.exe" h "I:\Test Folder\*.*"|@FindSTR.exe /ei "\.exe \.msi""`)do @for /f useback^tokens^=2delims^=^= %I in (`"@"C:\Program Files\7-Zip\7z.exe" l -slt "H:\Q1634964.7z" -p"123456"|@FindSTR.exe /bi "CRC"|FindSTR.exe /c:"%~i""`)do @"C:\Program Files\7-Zip\7z.exe" x "H:\Q1634964.7z" -y -o"%temp%" "%~k" -r -p"123456"|@Findstr.exe /e "Ok" >nul && <con: @rename "%temp%\%~k" "%~i %~k") & @popd
  • 在你的 bat/cmd 文件中:
@echo off 

pushd %__AppDir__%
Setlocal EnabledelayeDexpansion
set "_7z=C:\Program Files\7-Zip\7z.exe" 

for /f useback^tokens^=1-2* %%i in (`""!_7z!" h "I:\Test Folder\*.*"|FindSTR.exe /ei "\.exe \.msi""
    `)do for /f useback^tokens^=2delims^=^= %%I in (`""!_7z!" l -slt "H:\Q1634964.7z" -p"123456"|FindSTR.exe /bi "CRC"|FindSTR.exe /c:"%%~i""
        `)do "!_7z!" x "H:\Q1634964.7z" -y -o"%temp%" "%%~k" -r -p"123456"|Findstr.exe /e "Ok" >nul && <con: rename "%temp%\%%~k" "%%~i %%~k"

<con: popd & endlocal & goto :eOf

其他资源

其他资源/

相关内容