Listar arquivos zip com menos de um número específico de arquivos

10

Eu tenho milhares de .zip arquivos em uma pasta. Desejo descobrir quais arquivos zip têm menos de 15 arquivos neles.

Eu sei que unzip -l pode listar o conteúdo dos arquivos zip, mas não sei como criar uma saída de arquivos zip com menos de 15 arquivos.

    
por yarone 28.02.2017 / 09:24

4 respostas

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

Isso lista os arquivos .zip com menos de 15 arquivos para stdout (no terminal), portanto, se você quiser criar um arquivo de lista, poderá tee out ou redirecionar. Aqui está mais legível, criando um arquivo de lista no final, assim como imprimindo no terminal

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

Notas

  • for z in *.zip faz um loop sobre os arquivos que terminam com .zip e faz algo para cada um, representado pela variável z referenciada com $z
  • if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?//p') < 15 )) faz o unzip contar os arquivos, extrai o número da saída (com certeza há uma maneira mais clara de extrair apenas o número, mas eu sei sed , então eu usei - veja @muru's comment para um maneira mais simples que pode ser mais rápida com muitos arquivos) e testar se é menor que 15, e se é
  • echo "$z" , em seguida, imprima o nome do arquivo
  • | tee small-zip-list também imprime a saída para um novo arquivo, bem como no terminal
por Zanna 28.02.2017 / 09:50
9

Uma opção de python tardia, usando python ' zipfile , (como sugerido por @muru, obrigado!)

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

Como usar

  1. Copie o script em um arquivo vazio, salve-o como get_zips.py
  2. Execute-o com o diretório e o número desejado (mínimo) de arquivos dentro, por exemplo:

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

Explicação

O script:

  • lista .zip arquivos dentro de um diretório:

    for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:
    
  • Olha dentro do arquivo e conta o número de arquivos:

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

    Imprime somente o arquivo (+ caminho) se o número de itens listados for menor que n .

por Jacob Vlijm 28.02.2017 / 10:47
9

Usando o 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 também pode ser feito com script.

Crie o 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

Salve na pasta inicial & amp; Torne-o executável com chmod +x zip.sh e execute a partir do terminal ./zip.sh

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

  • unzip -l $i contará o número de arquivos do respectivo zip arquivo & amp; da sua saída,

  • awk 'END {print $(NF-1)}' grep que conta apenas o número, se for menos de 15, então ele irá imprimir o nome do arquivo.

por d a i s y 28.02.2017 / 10:26
5

O Perl também tem um pacote para lidar com arquivos zip, Archive::Zip . O script abaixo pega arquivos zip como argumentos de linha de comando e fornece saída de linha de comando com nome e contagem de arquivos dentro do arquivo.

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

Execução de teste:

$ ./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
    
por Sergiy Kolodyazhnyy 28.02.2017 / 20:05