Перерахуйте поштові файли, у яких менше певної кількості файлів


10

У мене .zipв одній папці тисячі файлів. Я хочу знайти, які поштові файли містять менше 15 файлів.

Я знаю, що unzip -lможе перераховувати вміст zip-файлів, але я не знаю, як створити висновок zip-файлів, які містять менше 15 файлів.

Відповіді:


14
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 також друкувати вихід у новий файл, а також у термінал

Дякую @Zanna, я намагався запустити сценарій пожежі, і він завжди показує всі .zip імена файлів у папці, навіть якщо я зменшую форму числа 15 на щось менше, він показує всі .zip файли в папці.
yarone

@yarone так шкода, я пропустив пробіл! Я це виправив зараз, сподіваюся, спробуйте ще раз
Zanna

6
Може бути трохи простіше у використанні zipinfo: zipinfo -1 foo.zip | wc -lабоzipinfo -t foo.zip | awk '{print $1}'
muru

@yarone найкраще вітаємо! : D
Занна

+1 Використовується одне з наступних: awk, sed, grep;)
Nonny Moose

9

Пізній варіант 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)

Як користуватись

  1. Скопіюйте скрипт у порожній файл, збережіть його як get_zips.py
  2. Запустіть його за допомогою каталогу та потрібної (мінімальної) кількості файлів всередині, наприклад:

    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.


1
Пітон? zipfile !
муру

@muru ще раз дякую, що має значення :)
Яків Влійм

9

Використання 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, воно друкує ім'я файлу.


5

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


0

Отримайте загальну кількість файлів за допомогою zipinfo:

$ for f in *.zip; do \
  a=($(zipinfo -t "$f")); \
  (($a > 15)) && echo $f; done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.