I was searching for an answer to this exact problem, and found the answer within the link provided by Nisse Knudsen, but for me the -ba
undocumented switch did not work on its own to do what I needed it to, nor does this switch alone (nor Nisse's answer) appear to fully answer the OP's question - OP wants to know how to get just the Name (of each file) and -ba
alone will not always work when parsing data from a .7z
file. I would have made a comment rather than a full answer, but I have not earned enough rep to comment and I believe this information is still relevant and accurate to present, and my "comment" would have been too long anyway.
Referencing the link provided by Nisse (https://superuser.com/a/1073272/542975) using the -slt
switch formats the output in a much more readable format (for looping/parsing purposes) which a simple For /f
loop in a batch file can parse and give you what is needed.
Let me list a few changes in output for you to see what each switch is doing.
THIS: 7z.exe l "C:\Some Directory\Some FileIZipped.zip"
7-Zip [64] 15.12 : Copyright (c) 1999-2015 Igor Pavlov : 2015-11-19
Scanning the drive for archives:
1 file, 9986888 bytes (10 MiB)
Listing archive: C:\Some Directory\Some FileIZipped.zip
--
Path = C:\Some Directory\Some FileIZipped.zip
Type = zip
Physical Size = 9986888
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2017-07-18 12:19:04 ....A 240789 109401 A_RandomFile.doc
2017-07-05 13:32:42 ....A 19148800 9877487 Another_Random File with Spaces.mov
------------------- ----- ------------ ------------ ------------------------
2017-07-18 16:30:44 19389589 9986888 2 files
Becomes THIS: 7z.exe l -slt "C:\Some Directory\Some FileIZipped.zip"
7-Zip [64] 15.12 : Copyright (c) 1999-2015 Igor Pavlov : 2015-11-19
Scanning the drive for archives:
1 file, 9986888 bytes (10 MiB)
Listing archive: C:\Some Directory\Some FileIZipped.zip
--
Path = C:\Some Directory\Some FileIZipped.zip
Type = zip
Physical Size = 9986888
----------
Path = A_RandomFile.doc
Folder = -
Size = 240789
Packed Size = 109401
----[10 lines of jargon removed for clarity]----
Path = Another_Random File with Spaces.mov
Folder = -
Size = 19148800
Packed Size = 9877487
----[10 lines of jargon removed for clarity]----
Adding in the -ba
command simplifies the format a little further, preventing the need to skip the header lines (I reference this in comments in the for loop as shown in the script sample at the end).
This further becomes: 7z.exe l -ba -slt "C:\Some Directory\Some FileIZipped.zip"
Path = A_RandomFile.doc
Folder = -
Size = 240789
Packed Size = 109401
----[10 lines of jargon removed for clarity]----
Path = Another_Random File with Spaces.mov
Folder = -
Size = 19148800
Packed Size = 9877487
----[10 lines of jargon removed for clarity]----
I am using this as a method of file-comparing an archive (zip/7z/rar) against the actual directory to make a mirror copy where the directory is the master. To do this I am parsing a file containing the output of my 7z list command. I suppose I could iterate the for loop directly from the 7z command instead, but I have found this to be slower in some situations when there's a large amount of data within the archives.
I have had multiple instances where trying to parse the standard output fails - it occurs when listing contents of a .7z
archive as shown below. This is not -EASILY- resolved using a for loop parsing for spaces. What would be Token 5
for most lines (showing as the Compressed Space) end up becoming the filename which is reserved in .zip
format archives as Token 6
so then you have a very messy situation which is a nightmare to plan for. This is also the exact problem the OP is referencing in the provided example given.
Example similar to what OP Provided:
7-Zip [64] 15.12 : Copyright (c) 1999-2015 Igor Pavlov : 2015-11-19
Scanning the drive for archives:
1 file, 446600 bytes (437 KiB)
Listing archive: C:\Some Directory\Some _OTHER_ FileIZipped.7z
--
Path = C:\Some Directory\Some _OTHER_ FileIZipped.7z
Type = 7z
Physical Size = 446600
Headers Size = 283
Method = LZMA2:22
Solid = +
Blocks = 1
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2020-08-28 15:06:46 D.... 0 0 SomeDirectoryInside
2020-08-28 15:06:46 D.... 0 0 SomeDirectoryInside\OtherDir
2020-08-28 15:06:46 D.... 0 0 SomeDirectoryInside\Zips
2020-08-28 15:13:14 ..... 1064960 446317 SomeDirectoryInside\Zips\Some_File.Doc
2020-08-28 15:08:02 ..... 313080 SomeDirectoryInside\Zips\Some_Other_File.Doc
2020-08-28 15:07:34 ..... 1561728 SomeDirectoryInside\Zips\Foo.mov
2020-08-28 15:07:46 ..... 262144 SomeDirectoryInside\Zips\Fancy.Doc
2020-08-28 15:07:26 ..... 262144 SomeDirectoryInside\Zips\Fancy2.Doc
------------------- ----- ------------ ------------ ------------------------
2020-08-28 15:13:14 3464056 446317 5 files, 3 folders
Below is a batch script sample I wrote to put the 7z.exe
output into a file and then pulling the data from the file and getting just what I need. Forgive the multiple REM lines - I prefer this method of commenting instead of long single -line strings so readers do not have to scroll the code block to the right in order to read.
Because of how For /f
iterates through data, we need to ensure token %%c
is not blank. I am using this method because sometimes our files have spaces in the names, and we are parsing the 7z
output using Spaces as the Delimiter.
Token 3*
will give you two separate tokens you can check -- Tokens %%b
[ Token 3 ] and %%c
[ Token * ] - if %%c
is blank - we know %%b
has no spaces and can safely be echoed to whichever file we need or set as a variable to use later, etc.
@Echo Off
REM Sending the output of 7z into a file to use later
7z.exe l -slt "SomeFileIZipped.zip" >"ZipListRAW.txt"
REM Example of 7z.exe command with '-ba' switch
REM 7z.exe l -ba -slt "SomeFileIZipped.zip"
REM If you do not use '-ba' in the 7z command above, you can simply skip the first
REM 11-12 lines of the file to get ONLY the filenames (skips past first line containing
REM "Path" which contains the original archive filename.
For /f "Usebackq Skip=11 Tokens=1,3* Delims= " %%a in ("ZipListRAW.txt") do (
REM Checking if %%a equals word "Path"
If "%%a"=="Path" (
If [%%c]==[] (
Echo %%b
) ELSE (
Echo %%b %%c
)
)
)