Extract list of file names in a zip archive when `unzip -l`
Assuming none of the files have spaces in names:
unzip -l filename.zip | awk '{print $NF}'
My unzip output has both a header and footer, so the awk script becomes:
unzip -l filename.zip | awk '/-----/ {p = ++p % 2; next} p {print $NF}'
A version that handles filenames with spaces:
unzip -l filename.zip | awk '
/----/ {p = ++p % 2; next}
$NF == "Name" {pos = index($0,"Name")}
p {print substr($0,pos)}
'
How can I list the files in a zip archive without decompressing it?
Perreal's answer is right, but I recommend installing atool (look for it in your distribution's package manager). Then, for any kind of archive file, bzip2, gzip, tar... you have just one command to remember :
als archive_name
How to extract last file added to an zip archive
Try this:
unzip /path/to/archive/dec2020.zip $(unzip -l /path/to/archive/dec2020.zip | sort -k2 | tail -5 | head -1 | awk '{ print $4 }')
$() expands the first command and uses the expansion in the second. We list the archive entries in date order and use tail, head and sort to get the line required. We then use awk to print out the file path (the 4th space delimited field)
Alternatively, this can be done with the awk system function to action the unzip.
unzip -l /path/to/archive/dec2020.zip | sort -k2 | tail -5 | head -1 | awk '{ system("unzip /path/to/archive/dec2020.zip "$4) }'
List zip file entries with special characters like emojis
It doesn't seem possible to accurately list the files in a zip archive with unzip
(tested with unzip 6.00
); you'll have to select an other tool.
I chose perl
in my answer because it has the required functionality in its core library. Here I used a newline
as delimiter (-l
) but you should replace it with a NULL-BYTE
(-l0
) if you want to be able to read and process the outputted paths 100% accurately from bash:
perl -l -e '
use IO::Uncompress::Unzip;
$zip = IO::Uncompress::Unzip->new($ARGV[0]);
while($zip->nextStream()) {
print $zip->getHeaderInfo()->{Name}
}
' foo.zip
test/
test/.txt
remark: Python also have a ZipFile
module in its core library. I didn't post any Python solution because of the encoding issues of its stdout
. The fixes aren't compatible between Python versions...
Extract certain files from .zip
Thanks to comment from @user20650.
Use two calls to unzip
. First with list=TRUE
just to get the $Name
for the files. Second with files=
to extract only the files whose names match the pattern.
zipped_csv_names <- grep('\\.csv$', unzip('some_archive.zip', list=TRUE)$Name,
ignore.case=TRUE, value=TRUE)
unzip('some_archive.zip', files=zipped_csv_names)
comb_tbl <- rbindlist(lapply(zipped_csv_names,
function(x) cbind(fread(x, sep=',', header=TRUE,
stringsAsFactors=FALSE),
file_nm=x)), fill=TRUE )
Listing the contents of zip files within a tar file
Starting with tar, you can get it to write to stdout with the -O command line option.
Next to the unzip part of the problem. The standard Linux infozip versions of zip/unzip don't support reading input from stdin. The funzip command, which is part of infozip can read from stdin, reads from stdin but it only supports uncompression. It doesn't have an option to list the contents.
Luckily Java jar files are really just zip files with a well-defined structure and the jar command can read from stdin and list the contents of the input file
So, assuming you have a tar file called my.tar that only contains zip files, something like this should list the names of the files in the embedded zip files
tar xOf my.tar | jar -t
Unzip ZIP file and extract unknown folder name's content
I think your approach is a good one. Step 2 could be improved my extracting to a newly created directory (later deleted) so that "detection" is trivial.
# Bash (minimally tested)
tempdest=$(mktemp -d)
unzip -d "$tempdest" TEMPLATE1.ZIP
dir=("$tempdest"/*)
if (( ${#dir[@]} == 1 )) && [[ -d $dir ]]
# in Bash, etc., scalar $var is the same as ${var[0]}
mv "$dir"/* /mysite/user_uploaded_templates/myrandomname
else
echo "rejected"
fi
rm -rf "$tempdest"
How to get a list of directories in a zip?
To list only directories:
unzip -l foo.zip "*/"
Output (e.g.):
Archive: foo.zip
Length Date Time Name
--------- ---------- ----- ----
0 2015-09-10 20:10 work/
0 2015-08-31 10:45 work/test1/
0 2015-08-31 10:50 work/test1/cc/
0 2015-08-31 10:45 work/test1/dd/
0 2015-08-31 10:45 work/test1/aa/
0 2015-08-31 10:45 work/test1/bb/
0 2015-09-09 21:17 work/tmp/
0 2015-08-23 18:49 work/tmp/work/
0 2015-09-08 19:33 work/tmp/work/loop/
0 2015-08-15 16:00 work/tmp/work/1/
0 2015-08-15 16:00 work/1/
0 2015-08-24 18:40 work/dir/
0 2015-09-05 18:07 work/rename/
--------- -------
0 13 files
or use
zipinfo -1 foo.zip "*/"
Output (e.g.):
work/
work/test1/
work/test1/cc/
work/test1/dd/
work/test1/aa/
work/test1/bb/
work/tmp/
work/tmp/work/
work/tmp/work/loop/
work/tmp/work/1/
work/1/
work/dir/
work/rename/
Related Topics
Find Directories Having Size Greater Than X Mb
Delete Whitespace in Each Begin of Line of File, Using Bash
Ubuntu Equivalent of Yum's Whatprovides, to Find Which Package Provides a File
Running Shell Script Using .Env File
Will Ctrl+C Send Sigint Signals to Both Parent and Child Processes in Linux
Linux Terminal: How to Capture or Watch Other Terminal Session
Bumping Version Numbers for New Releases in Associated Files (Documentation)
Errors in Make File:*** Missing Separator. Stop
Effects of Removing All Symbol Table and Relocation Information from an Executable
Adding Users to Sudoers Through Shell Script
Linux - Write Commands from One Terminal to Another
Debugging in Pycharm with Sudo Privileges
Error: Ld.So: Object 'Libgtk3-Nocsd.So.0' from Ld_Preload Cannot Be Preloaded
How to Release Hugepages from the Crashed Application
How to Set Cap_Sys_Nice Capability to a Linux User