Lista plików zip, które zawierają mniej niż określoną liczbę plików

10

Mam tysiące .zipplików w jednym folderze. Chcę dowiedzieć się, które pliki zip zawierają mniej niż 15 plików.

Wiem, że unzip -lmoże wyświetlać zawartość plików zip, ale nie wiem, jak utworzyć wyjście plików zip, które zawierają mniej niż 15 plików.

Yarone
źródło

Odpowiedzi:

14
for z in *.zip; do if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 )); then echo "$z"; fi; done

Wyświetla listę .zipplików zawierających mniej niż 15 plików na standardowe wyjście (w terminalu), więc jeśli chcesz utworzyć plik listy, możesz teewyjść lub przekierować. Tutaj jest to bardziej czytelne, tworząc plik listy na końcu, a także drukując w terminalu

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

Notatki

  • for z in *.zipzapętlaj pliki kończące się na .zipi zrób coś dla każdego z nich, reprezentowane przez zmienną, zdo której się odwołuje$z
  • if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 ))rozpakuj liczenie plików, wyodrębnij liczbę z danych wyjściowych (z pewnością jest bardziej uporządkowany sposób, aby wyodrębnić tylko liczbę, ale wiem sed, że ją wykorzystałem - zobacz komentarz @ muru dla prostszego sposobu, który może być szybszy w przypadku wielu plików) i sprawdź, czy jest mniej niż 15, a jeśli tak
  • echo "$z" następnie wydrukuj nazwę pliku
  • | tee small-zip-list również wypisuje dane wyjściowe do nowego pliku, a także w terminalu
Zanna
źródło
Dziękuję @Zanna, próbowałem uruchomić skrypt pożarów i zawsze pokazuje on wszystkie nazwy plików .zip w folderze, nawet jeśli zmniejszam liczbę od 15 do czegoś mniejszego, pokazuje wszystkie pliki .zip w folderze.
yarone
@yarone bardzo przepraszam, spudłem! Naprawiłem to teraz, mam nadzieję, spróbuj ponownie
Zanna
6
Może być nieco łatwiejszy w użyciu zipinfo: zipinfo -1 foo.zip | wc -llubzipinfo -t foo.zip | awk '{print $1}'
muru
@yarone jak najbardziej mile widziany! : D
Zanna
+1 Zastosowano jedną z następujących opcji: awk, sed, grep;)
Nonny Moose
9

Późna opcja Pythona, używając python's zipfile, (jak sugeruje @muru, dzięki!)

#!/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)

Jak używać

  1. Skopiuj skrypt do pustego pliku i zapisz go jako get_zips.py
  2. Uruchom go z katalogiem i pożądaną (minimalną) liczbą plików w środku, np .:

    python3 /path/to/get_zips.py /full/path/to/directory_with_zips 15
    

Wyjaśnienie

Scenariusz:

  • wyświetla listę .zipplików w katalogu:

    for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:
  • Przeszukuje plik i liczy liczbę plików:

    if len(ZipFile(file, "r").namelist()) < n:
        print(file)
    

    Drukuje plik (+ ścieżkę) tylko wtedy, gdy liczba wymienionych elementów jest mniejsza niż n.

Jacob Vlijm
źródło
1
Pyton? plik zip !
muru
@muru jeszcze raz dziękuję, to robi różnicę :)
Jacob Vlijm
9

Za pomocą 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

Lub można to również zrobić za pomocą skryptu.

Utwórz skrypt 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

Zapisz go w folderze domowym chmod +x zip.shi uruchom go z terminala./zip.sh

Tutaj if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 )),

  • unzip -l $i policzy liczbę plików z odpowiedniego pliku zip i jego wyniku,

  • awk 'END {print $(NF-1)}' grep, który zlicza tylko liczbę, jeśli jest mniejsza niż 15, to wypisze nazwę pliku.

stokrotka
źródło
5

Perl posiada również pakiet do obsługi archiwów zip, Archive::Zip. Poniższy skrypt przyjmuje pliki zip jako argumenty wiersza poleceń i udostępnia dane wyjściowe wiersza polecenia z nazwą i liczbą plików w archiwum.

#!/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());
    }
}

Testowe uruchomienie:

$ ./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
Sergiy Kolodyazhnyy
źródło
0
for z in *.zip; do if (( $(unzip -Z1 "$z" | wc -l) < 15 )); then echo "$z"; fi;done
użytkownik1048382
źródło
drobna zmiana w kodzie @ Zanny „$ (rozpakuj -Z1„ $ z ”| wc -l)”
user1048382
0

Uzyskaj całkowitą liczbę plików za pomocą zipinfo:

$ for f in *.zip; do \
  a=($(zipinfo -t "$f")); \
  (($a > 15)) && echo $f; done
bac0n
źródło