3

What is the simplest way to compare a zip file and a directory that has been extracted from the zip file? I would like to delete the zip file if they are the same.

Example. Need to check if Archive.zip and travel_photos/ directory contain the same files (i.e., if all files inside Archive.zip have been correctly extracted to travel_photos/).

Limitation. I cannot change how the archive creation and the extraction was done. These files are given to me and I need to check them afterwards. This means, I cannot create a file with the checksums of all files inside Archive.zip.

Requirement. I do not want to create another zip archive from travel_photos/ because I need to work with large directories and may not have enough space to write additional big files. For this reason, points 2-5 below are not good, although I tried them to see what might work.

What I've tried so far.

  1. compare md5sum Archive.zip and (cd travel_photos; zip -rqq - *) | md5sum,
  2. compare (cd travel_photos; zip -rqq ../test.zip *); md5sum test.zip and md5sum Archive.zip,
  3. compare unzip -p test.zip | md5sum and unzip -p Archive.zip | md5sum
  4. zcmp test.zip Archive.zip (also with zdiff)
  5. unzip -vql test.zip | sort -k8 | md5sum and unzip -vql Archive.zip | sort -k8 | md5sum

Partial solution. If I change the last example above to remove the fields Cmpr and Size (somehow the file sizes are different in the two archives even though the files are exactly the same?) and remove the total archive size from the first two lines, then I can verify that the archives are the same.

diff -W200 -y <(unzip -vql test.zip | sort -k8 | awk '{if(NR>2) print ($1"\t"$2"\t"$5"\t"$6"\t"$7"\t"$8)}' ) <(unzip -vql Archive.zip | sort -k8 | awk '{if(NR>2) print ($1"\t"$2"\t"$5"\t"$6"\t"$7"\t"$8)}' ) --suppress-common-lines

The drawback of this solution is that I need to create and save test.zip to disk. Is there a way to do this comparison but between the directory travel_photos/ and the zipfile Archive.zip? I tried to pipe the output of zip command as below but it didn't work.

diff -W200 -y <(unzip -vql Archive.zip | sort -k8 | awk '{if(NR>2) print ($1"\t"$2"\t"$5"\t"$6"\t"$7"\t"$8)}' ) < ((cd travel_photos; zip -rqq - *) > unzip -vql | sort -k8 | awk '{if(NR>2) print ($1"\t"$2"\t"$5"\t"$6"\t"$7"\t"$8)}' ) --suppress-common-lines
3
  • Welcome, there a spaces in the file names? And there are subdirectories? Nov 11, 2021 at 22:22
  • No spaces in file names and no subdirectories.
    – vpk
    Nov 11, 2021 at 23:09
  • @schrodigerscatcuriosity I think I saw an answer yesterday but it seems to have disappeared?
    – vpk
    Nov 13, 2021 at 3:20

1 Answer 1

0

You can use "folderdiff" (https://pypi.org/project/folderdiff/) to compare the contents of a folder with the contents of a ZIP archive, without storing the files to disk.

It's also possible to compare the contents of 2 ZIP archives.

"folderdiff" was created to compare a webapplication (e.g. wordpress) with a trusted source and find modified or added files which can contain backdoors.

For each file a SHA256 hash is calculated and compared with the trusted source. "folderdiff" requires 2 arguments. The first one is the trusted source and the second one is the folder, which should be compared to the trusted source.

Following example shows how to find backdoors in an existing wordpress installation:

$ folderdiff wordpress-6.0.3-de_AT.zip /var/www/ --prefix wordpress/
===================== Added ======================
+ webshell.php
==================== Modified ====================
* index.php

Disclosure: I'm the author of folderdiff

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .