Bash: How to check if a zip file contain a specified path/file.ext?
Asked Answered
B

4

10

I've to handle 46 .zip file according to their internal structure.

The first usefull check to branch the elaboration is check if a specific file is presente in the .zip.

Actually i'm unzipping and testing the existence of unzipped file.

But, I ask you, is there a way to check if a file is inside a zip file without extract it entirely, using only bash commands?

Benoite answered 4/9, 2017 at 9:37 Comment(3)
unzip -l lists all files in a zip file.Doall
@pfnuesel: and how to check for a specific file?Benoite
unzip -Z1 file.zip | grep fileElectrophilic
P
16

To check for specific file, you can combine unzip -l with grep to search for that file. The command will look something like this

unzip -l archive.zip | grep -q name_of_file && echo $?

What this does is it lists all files in archive.zip, pipes them to grep which searches for name_of_file. grep exits with exit code 0 if it has find a match. -q silences the output of grep and exits immediatelly with exit code 0 when it finds a match. The echo $? will print the exit code of grep. If you want to use it in if statement, your bash script would look like this:

unzip -l archive.zip | grep -q name_of_file;
if [ "$?" == "0" ]
then
    ...
fi;
Phonograph answered 4/9, 2017 at 10:15 Comment(5)
unzip takes lists of files itself, including when you list with -l so you don't need grep: unzip -l archive.zip name_of_fileQuanta
The first version (with &&) will not work as expected in case name_of_file is not part of the ZIP archive. Since whenever the left-hand side of && already fails, the right-hand side is not even executed.Magnesite
@Magnesite that is indeed true, but if you only want to find check for that file and if file is not found, you won't see anything on screen, since echo will not be executed. On the other hand, the second script shows the example with semicolon, since in that case you need the outputPhonograph
This will also match any file "something$name_of_file"Rau
This method will fail if your filename has newline characters or any other non-standard characterBohlen
E
3

on command-line you can try:

$ if [[ `unzip -Z1 audio.zip | grep help.mp3` ]];then echo 'yes';fi

if the help.mp3 is found the output would be yes

see:

help [[  

on

Electrophilic answered 4/9, 2017 at 10:33 Comment(1)
Warning: this will also match selfhelp.mp3 and similar.Rau
H
2

Another way to do is:

if [[ -n `unzip -Z archive.zip file 2>/dev/null` ]]; then
    echo 'yes'
else
    echo 'no'
fi
Holdover answered 14/1, 2019 at 10:23 Comment(1)
maybe also rediredt stdout: like ``` >/dev/null 2>/dev/null ```Cask
B
2

Most of these methods work as expected, except when the filename has non-standard characters such as newlines. Example:

$ unzip -l foo.zip
Archive:  foo.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  05-06-2020 12:25   foo^Jbar
        0  05-06-2020 12:25   foonbar
---------                     -------
        0                     2 files

As you see, the newline character is replaced with ^J. You could start using this in your grep, but then you need to know all other Control characters by heart.

The following methods works always:

$ unzip -Z foo.zip foo$'\n'bar &>/dev/null && echo true || echo false
true
$ unzip -l foo.zip foo$'\n'bar &>/dev/null && echo true || echo false
true
Bohlen answered 6/5, 2020 at 12:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.