Répertorier les fichiers zip contenant moins d'un nombre spécifique de fichiers

10

J'ai des milliers de .zipfichiers dans un dossier. Je souhaite trouver les fichiers zip contenant moins de 15 fichiers.

Je sais que cela unzip -lpeut répertorier le contenu des fichiers zip, mais je ne sais pas comment créer une sortie de fichiers zip contenant moins de 15 fichiers.

yarone
la source

Réponses:

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

Cela répertorie les .zipfichiers avec moins de 15 fichiers à stdout (dans le terminal), donc si vous souhaitez créer un fichier de liste, vous pouvez le teeretirer ou le rediriger. Ici, c'est plus lisible, la création d'un fichier de liste à la fin ainsi que l'impression dans le 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

Remarques

  • for z in *.zipfaire une boucle sur les fichiers se terminant par .zipet faire quelque chose pour chacun, représenté par la variable zréférencée par$z
  • if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 ))faire décompresser les fichiers, extraire le nombre de la sortie (il y a sûrement un moyen plus ordonné d'extraire uniquement le nombre, mais je sais sedque je l'ai utilisé - voir le commentaire de @ muru pour un moyen plus simple qui peut être plus rapide avec de nombreux fichiers) et tester si elle est inférieure à 15, et si elle est
  • echo "$z" puis imprimez le nom du fichier
  • | tee small-zip-list également imprimer la sortie dans un nouveau fichier, ainsi que dans le terminal
Zanna
la source
Merci @Zanna j'ai essayé d'exécuter le script incendies et il montre toujours tous les noms de fichiers .zip dans le dossier, même si je diminue le nombre de 15 à quelque chose de plus petit, il montre tous les fichiers .zip dans le dossier.
yarone
@yarone donc désolé, j'ai raté un espace! Je l'ai corrigé maintenant j'espère, veuillez réessayer
Zanna
6
Pourrait être légèrement plus facile à utiliser zipinfo: zipinfo -1 foo.zip | wc -louzipinfo -t foo.zip | awk '{print $1}'
muru le
@yarone le bienvenu! : D
Zanna
+1 Utilisé l'un des éléments suivants: awk, sed, grep;)
Nonny Moose
9

Une option python tardive, utilisant python's zipfile, (comme suggéré par @muru, merci!)

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

Comment utiliser

  1. Copiez le script dans un fichier vide, enregistrez-le sous get_zips.py
  2. Exécutez-le avec le répertoire et le nombre de fichiers (minimum) souhaité à l'intérieur, par exemple:

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

Explication

Le scénario:

  • répertorie les .zipfichiers dans un répertoire:

    for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:
  • Regarde à l'intérieur du fichier et compte le nombre de fichiers:

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

    N'imprime le fichier (+ chemin d'accès) que si le nombre d'éléments répertoriés est plus petit n.

Jacob Vlijm
la source
1
Python? zipfile !
muru
@muru merci encore, cela fait une différence :)
Jacob Vlijm
9

Utiliser 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

Ou cela peut aussi être fait avec un script.

Créer un 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

Enregistrez-le dans le dossier d'accueil et rendez-le exécutable avec chmod +x zip.shet exécutez à partir du terminal./zip.sh

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

  • unzip -l $i il comptera le nombre de fichiers du fichier zip respectif et de sa sortie,

  • awk 'END {print $(NF-1)}' grep ce nombre de comptage uniquement, s'il est inférieur à 15, il affichera le nom du fichier.

Marguerite
la source
5

Perl dispose également d' un package pour le traitement des archives zip, Archive::Zip. Le script ci-dessous prend les fichiers zip comme arguments de ligne de commande et fournit une sortie de ligne de commande avec le nom et le nombre de fichiers dans l'archive.

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

Essai:

$ ./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
la source
0
for z in *.zip; do if (( $(unzip -Z1 "$z" | wc -l) < 15 )); then echo "$z"; fi;done
user1048382
la source
une modification mineure du code de @ zanna "$ (décompressez -Z1" $ z "| wc -l)"
user1048382
0

Obtenez le nombre total de fichiers en utilisant zipinfo:

$ for f in *.zip; do \
  a=($(zipinfo -t "$f")); \
  (($a > 15)) && echo $f; done
bac0n
la source