我如何告诉 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 [ ] 字符串%%~i
H: \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