How do i unzip files with 7z and do not replace files that have the same name but different hash?

How can i tell 7z to extract all the files in the directory, tell it to do not replace files that have the same name but different hash? preferably tell it to extract the files and rename them to their hash?

for example lets say i extract two zip files, both have x.dll but with a different hash (different version). i want to keep both, but if its the same version (same hash), then only keep one. and preferably rename the extracted file to its hash, how to do it?

Right now I am extracting this way :

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

(not all the files contain password, but if they do, its the same, so correct me if I am doing it wrong)

To give context, i have a large number of installer files (.msi or .exe files that contain a lot of exes inside them), and i need to extract all the unique executables inside of them

Right now i am using the linux version of 7z, but i can use the Windows version too (inside a VM)

3

1 Answer

So, this is my \Test Folder\*.*:

I:\> tree /f /aFolder 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

These are the CRCs of my files [.exe | .msi] present in my 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.msi754077D4 2018 extract y file 001.msi324BD0AB 2112 extract y file 002.exeCA78246F 2098 extract y file 003.exe26176047 9164 extract y file 003.msi
  • Obs.: For the Output of the 7z h command used, and filtered by Findstr, the size is disposable, but in getting the CRC and name, we can use in another loop to find that CRC and extract the relevant file when another one matches with an item in the Test Folder.
variable ==> %%~itokens^=1 ==> 754077D4variable ==> %%~jtokens^= 2 ==> 2018variable ==> %%~ktokens^= * ==> extract y file 001.msitokens^=1-2* ==> 754077D4 2018 extract y file 001.msi 

These are the results of listing my 7z file and filtering so that I get the CRC strings in the output by FindSTR:

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

Using a For /F loop, I can get the CRC strings from each ".exe | .msi" file present in file inside the .7z, and use another For /F to find the string CRC in oputput, that match in a local file\loop in my \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""

Using a For /F loop, I can get the CRC [%%~i] strings from the files present in H: \Q1634964.7z, and with an additional For /F loop that uses the CRC obtained in the first loop, to get CRC and the names[%%~k] of the files when this occurred, you can easily extract file where the CRC matches and everything together would be...

  • In your command line:
@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
  • In Your bat file:
@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
  • Results:
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

If you don't need additional status outputs:

  • In your command line:
@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
  • In your batch file:
@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

To rename your files, where I assume you want/need is hash ("%%~i %%~k") resulting in the "Hash Name.eXtension" ==> "CA78246F extract y file 002.exe"

  • In your command line:
@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
  • In your bat/cmd file:
@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

Additional Resources 7-zip:

Additional Resources cmd/bat:

0

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like