This is far more fragile than using a real module, but takes advantage of the unzip utility which may be installed on your system. If it is not, then you're going to need to either install a module, install an unzip utility that can list the contents of zipfiles, or implement your own version of unzip that will read the contents of a zipfile.
#!/usr/bin/env perl
use strict;
use warnings;
my $filename = '/home/someuser/foo.zip';
my $read = `unzip -l $filename`; # Read in the output of the unzip -l
+command.
chomp(my @contents = split /\n/, $read);
# Note:
# $contents[0] contains the archive name.
# $contents[1] contains the header.
# $contents[2] contains a header delimiter ------.
# $contents[3] contains the first file listing.
# .....
# $contents[-3] contains last file listing.
# $contents[-2] contains a footer delimiter ------.
# $contents[-1] contains a summary.
+
my $pos = index $contents[1], 'Name'; # Find the 'Name'
+field. The start of that field is
# the position in
+subsequent lines where filenames
# begin.
+
+
my $n = 1; # Keep track of row number, just because.
+
+
foreach my $item (@contents[3 .. $#contents - 2]) { # Start with the f
+irst file entry, and end with the last file entry.
my $filename = substr($item, $pos); # Use our index po
+sition to look for a substring starting where
# the Name field b
+egan.
print $n++, ": $filename\n"; # Print out output
+.
}
One might ask why I used index and substr instead of a regular expression. The main reason is that it seemed easier
to base the location of filenames on the column of the header for filenames rather than trying to concoct a regular expression that would
find the filenames without being fooled by whitespace or entities that look like other fields in the original output. It's also hard
to know whether the assumption about what line number in the output is where filenames begin is a good assumption or not. It works for my system, and probably most other GNU/Linux systems, but YMMV.
The output of unzip -l on my system resembles this:
Archive: /home/davido/Downloads/dash-to-dock@micxgx.gmail.com.v61.she
+ll-extension.zip
Length Date Time Name
--------- ---------- ----- ----
0 2017-09-06 14:09 locale/zh_CN/LC_MESSAGES/
2754 2017-09-06 14:09 stylesheet.css
8981 2017-09-06 14:09 locale/es/LC_MESSAGES/dashtodock.mo
...(and so on...)
635 2017-12-23 17:29 metadata.json
--------- -------
659482 82 files
So by looking at this hopefully it's easier to see why I skip the first three lines, and the last two, and why it felt easier to grab the filenames starting at the column where the Name header begins.
But really, the right thing to do is to use a module that deals correctly with the nuances solutions like this one fail to consider, and that has benefitted from the refining process of bugfixes resulting from issues raised by the CPAN user community.
|