Respuestas:
for z in *.zip; do if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 )); then echo "$z"; fi; done
Esto enumera los .zip
archivos con menos de 15 archivos para stdout (en el terminal), por lo que si desea crear un archivo de lista, puede tee
salir o redirigir. Aquí es más legible, crear un archivo de lista al final e imprimir en el 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
for z in *.zip
recorrer los archivos que terminan con .zip
y hacer algo a cada uno, representado por la variable z
referenciada con$z
if (( $(unzip -l "$z" | sed -nr '$ s/.* ([0-9]+) files?/\1/p') < 15 ))
haga que descomprimir cuente los archivos, extraiga el número de la salida (seguramente hay una forma más ordenada de extraer solo el número, pero sé que sed
lo he usado; vea el comentario de @ muru para una forma más simple que puede ser más rápida con muchos archivos) y compruebe si es inferior a 15 y si esecho "$z"
luego imprima el nombre del archivo| tee small-zip-list
También imprima la salida a un nuevo archivo, así como en el terminal zipinfo
: zipinfo -1 foo.zip | wc -l
ozipinfo -t foo.zip | awk '{print $1}'
Una opción de python tardía, usando python
's zipfile
, (como lo sugirió @muru, ¡gracias!)
#!/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
Ejecútelo con el directorio y el número deseado (mínimo) de archivos dentro, por ejemplo:
python3 /path/to/get_zips.py /full/path/to/directory_with_zips 15
La secuencia de comandos:
enumera .zip
archivos dentro de un directorio:
for zp in [os.path.join(dr, f) for f in os.listdir(dr) if f.endswith(".zip")]:
Mira dentro del archivo y cuenta la cantidad de archivos:
if len(ZipFile(file, "r").namelist()) < n:
print(file)
Solo imprime el archivo (+ ruta) si el número de elementos de la lista es menor n
.
Usando 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
O también se puede hacer con script.
Crear 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
Guárdelo en la carpeta de inicio y hágalo ejecutable con chmod +x zip.sh
y ejecute desde la terminal./zip.sh
Aquí, if (( $(unzip -l $i | awk 'END {print $(NF-1)}') < 15 ))
,
unzip -l $i
contará el número de archivos del archivo zip respectivo y de su salida,
awk 'END {print $(NF-1)}'
grep ese número de recuento solamente, si es menor que 15, imprimirá el nombre del archivo.
Perl también tiene un paquete para el manejo de archivos zip, Archive::Zip
. El siguiente script toma archivos zip como argumentos de línea de comandos y proporciona una salida de línea de comandos con el nombre y el recuento de archivos dentro del archivo.
#!/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());
}
}
Prueba de funcionamiento:
$ ./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