Encontre imagens por tamanho: find / file / awk


9

Eu tenho tentado encontrar arquivos de imagem png a uma certa altura (acima de 500px). Eu sei que fileretornará as dimensões da imagem. Exemplo:

$ file TestImg1a.png

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

Mas preciso usar isso para encontrar todos os arquivos em um diretório com uma altura acima de 500px. Eu sei como imprimir todos os arquivos, independentemente da altura:

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

Mas como faço para limitar os US $ 7 a esses resultados maiores que 500?

Respostas:


7

Eu sei que isso é um pouco exagerado, mas isso funcionará sempre (mesmo que haja espaços no seu nome de arquivo) e independentemente de como o arquivo exibe as informações.

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

e imprime as dimensões da imagem e do arquivo

explicação:

  1. findtodos os arquivos denominados * .png em. e para cada um faça um arquivo nele

  2. use sedpara imprimir apenas o nome do arquivo e as dimensões e, em seguida, reordene para imprimir as dimensões primeiro

  3. use awkpara testar o primeiro número (altura da foto), certificando-se de que seja maior que 500 e, se tiver dimensões de impressão e nome de arquivo, se não fizer nada.


Obrigado. Eu tive que fazer uma pequena alteração - o $ 1 no argumento awk para $ 3. Mas isso definitivamente conseguiu para mim.
steve-er-rino


5

Eu sinto que algo diferente de utilitários de shell seria mais apropriado, por exemplo, 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 brincadeiras ao tentar analisar US $ 7; basta obter as dimensões diretamente. Sim, você precisará do módulo Image :: Info, mas, no CentOS / RHEL, é um pacote padrão, para que você possa executar yum install perl-Image-Info.


1
Embora o perl seja normalmente uma ótima solução, não é neste caso, especialmente porque não tenho Image :: Info nem a opção de instalar.
steve-er-rino

1
A solução perl é um pouco mais rápido do que o achado / arquivo / awk um, o que é bom, e no ubuntu derivados do módulo de amostra está disponívelapt-get install libimage-info-perl
rivimey

5

Você também pode usar o identifyImageMagick:

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

Ou no 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}'

não 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, lança $ 7 para um int antes de comparação, ou seja, int (US $ 7)> 500 .. na ausência de vazamento awk é recorrer a uma string literal comparar
Iruvar

Steve, de onde vem esse ","? Meu "arquivo" não produz isso. Mas, como Chandra disse: você pode forçar explicitamente US $ 7 a se tornar um número inteiro usando o método indicado em seu comentário.
tink

sua declaração awk só irá funcionar se o nome do arquivo não tem espaços nele
h3rrmiller

@tink the "," faz parte do arquivo retornado no meu ambiente.
steve-er-rino

0

Esta solução também funcionará. A última parte do código ( mv "$img" ./lowpixel) moverá os arquivos abaixo de uma largura e altura especificadas para uma pasta. No exemplo a seguir, todas as imagens jpg menores que 300 x 300 serão movidas para uma pasta chamada 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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.