Відповіді:
for z in *.zip; do if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 )); then echo "$z"; fi; done
Тут перераховані .zip
файли з менш ніж 15 файлами для stdout (у терміналі), тому якщо ви хочете створити файл списку, ви можете tee
вийти або перенаправити. Тут зрозуміліше - створення списку в кінці, а також друку в терміналі
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
for z in *.zip
петлю над файлами, що закінчуються, .zip
і кожен з них робить щось, представлене змінною, на яку z
посилається$z
if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 ))
змушуйте розпаковувати підрахунок файлів, витягувати число з виводу (напевно, є більш охайний спосіб витягнути лише число, але я знаю, sed
тому я його використав - див . коментар @ muru для більш простого способу, який може бути швидшим у багатьох файлах) і перевірити, чи менше 15, і чи єecho "$z"
потім надрукуйте ім’я файлу| tee small-zip-list
також друкувати вихід у новий файл, а також у термінал zipinfo
: zipinfo -1 foo.zip | wc -l
абоzipinfo -t foo.zip | awk '{print $1}'
Пізній варіант python, використовуючи python
's zipfile
, (як запропонував @muru, дякую!)
#!/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)
get_zips.py
Запустіть його за допомогою каталогу та потрібної (мінімальної) кількості файлів всередині, наприклад:
python3 /path/to/get_zips.py /full/path/to/directory_with_zips 15
Сценарій:
перелічує .zip
файли всередині каталогу:
for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:
Переглядає файл і підраховує кількість файлів:
if len(ZipFile(file, "r").namelist()) < n:
print(file)
Друкує файл (+ шлях) лише тоді, коли кількість перелічених елементів менше n
.
Використання 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
Або це також можна зробити за допомогою сценарію.
Створіть скрипт 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
Збережіть його в домашній папці та зробіть його виконуваним chmod +x zip.sh
та запустіть з терміналу./zip.sh
Ось if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 ))
,
unzip -l $i
він буде рахувати кількість файлів із відповідного zip-файлу та з його виводу,
awk 'END {print $(NF-1)}'
grep, що підраховує лише число, якщо воно менше 15, воно друкує ім'я файлу.
Perl також має пакет для обробки поштового архіву, Archive::Zip
. Сценарій, наведений нижче, приймає zip-файли як аргументи командного рядка та забезпечує вихід командного рядка з ім'ям та кількістю файлів у архіві.
#!/usr/bin/env perl
use strict;
use warnings;
use Archive::Zip;
foreach (@ARGV){
my $fh = Archive::Zip::->new();
if (my $error = $fh->read($_)){
die "Read error:" . $_;
}
if($fh->numberOfMembers() < 15 ){
printf("%s\t%d\n",$_,$fh->numberOfMembers());
}
}
Пробіг:
$ ./count_zip_contents.pl *.zip
129804-findmac.py.zip 1
Re%3a_China_and_East_Asia_%5bHIS-1250-010_31616.201730%5d%3a_Team_up_for_East_Asian_History_class.zip 4
University_Formal_jpg&tif.zip 5
indicator-places-master.zip 4
lab 5.zip 8
for z in *.zip; do if (( $(unzip -Z1 "$z" | wc -l) < 15 )); then echo "$z"; fi;done