Buscar imágenes por tamaño: buscar / archivo / awk


9

He estado tratando de encontrar archivos de imagen png de cierta altura (más de 500 px). Sé que filedevolverá las dimensiones de la imagen. Ejemplo:

$ file TestImg1a.png

TestImg1a.png: PNG image data, 764 x 200, 4-bit colormap, non-interlaced   

Pero necesito usar esto para encontrar todos los archivos en un directorio con una altura superior a 500 px. Sé cómo imprimir todos los archivos independientemente de la altura:

find . -name '*.png' | xargs file | awk '{print $7 " " $1}'

Pero, ¿cómo limito los $ 7 a esos resultados superiores a 500?

Respuestas:


7

Sé que esto es un poco exagerado, pero esto funcionará siempre (incluso si hay espacios en su nombre de archivo) e independientemente de cómo el archivo muestre la información.

find . -name '*.png' -exec file {} \; | sed 's/\(.*png\): .* \([0-9]* x [0-9]*\).*/\2 \1/' | awk 'int($1) > 500 {print}'

e imprime las dimensiones de la imagen y el archivo

explicación:

  1. findtodos los archivos llamados * .png debajo. y para cada uno haga un archivo

  2. use sedpara imprimir solo el nombre de archivo y las dimensiones y luego vuelva a ordenar para imprimir primero las dimensiones

  3. utilícelo awkpara probar el primer número (altura de la imagen) asegurándose de que sea superior a 500 y, si se trata de dimensiones de impresión y nombre de archivo, no haga nada.


Gracias. Tuve que hacer un ligero cambio: los $ 1 en el argumento awk a $ 3. Pero esto definitivamente me lo consiguió.
steve-er-rino


5

Siento que algo más que las utilidades de shell sería más apropiado, por ejemplo, Perl:

#!/usr/bin/perl

use File::Find;
use Image::Info qw(image_info dim);

find (\&check_height, './');

sub check_height {

  my $info = image_info( $_ );
  my ($width, $height) = dim( $info );
  print $_ . " has height $height\n" if ( $height > 500 );

}

Menos molestias al tratar de analizar $ 7; solo obtén las dimensiones directamente. Sí, necesitará el módulo Image :: Info, pero, en CentOS / RHEL, es un paquete estándar, por lo que puede ejecutarlo yum install perl-Image-Info.


1
Si bien Perl es normalmente una gran solución, no lo es en este caso, especialmente porque no tengo Image :: Info ni la opción de instalar.
steve-er-rino

1
La solución perl es algo más rápida que la de find / file / awk, lo cual es bueno, y en derivados de ubuntu, el módulo de información de imagen está disponible desdeapt-get install libimage-info-perl
rivimey

5

También puedes usar identifydesde ImageMagick:

find . -name \*.png -print0|xargs -0 identify -format '%h %f\n'|
awk '$1>500'|cut -d' ' -f2-

O en OS X:

mdfind 'kMDItemFSName=*.png&&kMDItemPixelHeight>500' -onlyin .

0
find . -name '*.png' -exec file "{}" \+ | awk -F"(: +PNG image data|,| x )" '$4 > 500 {print $4" "$1}'

no funciona:96, ./4/45445106_w185.png: 86, ./4/404358x_w185.png: 86, ./4/404341x_w185.png: 80, ./4/475986_w185.png: 621, ./4/481693_w185.png: 667, ./4/42513x_w185.png: 86, ./4/404372x_w185.png:
steve-er-rino

@tink, emite $ 7 a un int antes de la comparación, es decir, int ($ 7)> 500 ... en ausencia de un casting awk se recurre a una comparación de cadena literal
iruvar

Steve, ¿de dónde viene ese ","? Mi "archivo" no produce eso. Pero como dijo Chandra: puede forzar explícitamente $ 7 a convertirse en un número entero utilizando el método señalado en su comentario.
Tink

su declaración awk solo funcionará si el nombre de archivo no tiene espacios
h3rrmiller

@tink el "," es parte de lo que el archivo devuelve en mi entorno.
steve-er-rino

0

Esta solución también funcionará. La última parte del código ( mv "$img" ./lowpixel) moverá los archivos por debajo de un ancho y alto específicos a una carpeta. En el siguiente ejemplo, todas las imágenes jpg inferiores a 300x300 se moverán a una carpeta llamada lowpixel:

find -iname \*.jpg | while read img; do anytopnm "$img" | pamfile | perl -ane 'exit 1 if $F[3]<300 || $F[5]<300' || mv "$img" ./lowpixel; done

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.