Ответы:
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 файлами на стандартный вывод (в терминале), поэтому, если вы хотите создать файл списка, вы можете 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 ))
сделать unzip подсчитать файлы, извлечь число из выходных данных (конечно, есть более простой способ извлечь только число, но я знаю, 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 также есть пакет для работы с zip-архивами 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