List zip files which have less than a specific number of files
Solution 1:
for z in *.zip; do if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 )); then echo "$z"; fi; done
This lists the .zip
files with less than 15 files to stdout (in the terminal), so if you want to create a list file, you can tee
out or redirect. Here it is more readably, creating a list file at the end as well as printing in the terminal
for z in *.zip; do
if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 )); then
echo "$z"
fi
done | tee small-zip-list
Notes
-
for z in *.zip
loop over files ending with.zip
and do something to each one, represented by the variablez
referenced with$z
-
if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 ))
make unzip count the files, extract the number from the output (there's surely a tidier way to extract only the number, but I knowsed
so I've used it - see @muru's comment for a simpler way that may be faster with many files) and test whether it's less than 15, and if it is -
echo "$z"
then print the filename -
| tee small-zip-list
also print output to a new file, as well as in the terminal
Solution 2:
A late python option, using python
's zipfile
, (as suggested by @muru, thanks!)
#!/usr/bin/env python3
import os
import sys
from zipfile import ZipFile
dr = sys.argv[1]
for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:
if len(ZipFile(zp, "r").namelist()) < int(sys.argv[2]):
print(zp)
How to use
- Copy the script into an empty file, save it as
get_zips.py
-
Run it with the directory and the desired (minimum) number of files inside, e.g.:
python3 /path/to/get_zips.py /full/path/to/directory_with_zips 15
Explanation
The script:
-
lists
.zip
files inside a directory:for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:
-
Looks inside the file and counts the number of files:
if len(ZipFile(file, "r").namelist()) < n: print(file)
Only prints the file(+path) if the number of listed items is smaller then
n
.
Solution 3:
Using awk:
for i in ~/path/to/your/folder/*.zip; do if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 )); then echo "$i"; fi; done
Or it can be also done with script.
Create script zip.sh
#!/bin/bash
for i in ~/path/to/your/folder/*.zip; do
if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 )); then
echo "$i"
fi
done
Save it in home folder & Make it executable with chmod +x zip.sh
and run from terminal ./zip.sh
Here, if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 ))
,
unzip -l $i
it will count the number of files from respective zip file & from its output,awk 'END {print $(NF-1)}'
grep that count number only, if it is less than 15 then it will print the filename.