Rechercher des images par taille: trouver / fichier / awk

9

J'ai essayé de trouver des fichiers image png à une certaine hauteur (plus de 500 px). Je sais que filecela renverra les dimensions de l'image. Exemple:

$ file TestImg1a.png

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

Mais je dois l'utiliser pour trouver tous les fichiers dans un répertoire d'une hauteur supérieure à 500 px. Je sais comment imprimer tous les fichiers quelle que soit leur hauteur:

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

Mais comment limiter les 7 $ à ces résultats supérieurs à 500?

steve-er-rino
la source

Réponses:

7

Je sais que c'est un peu exagéré, mais cela fonctionnera à chaque fois (même s'il y a des espaces dans votre nom de fichier) et quelle que soit la façon dont le fichier affiche les informations.

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

et il imprime les dimensions de l'image et du fichier

explication:

  1. findtous les fichiers nommés * .png sous. et pour chacun faire un fichier dessus

  2. utiliser sedpour imprimer uniquement le nom de fichier et les dimensions, puis réorganiser pour imprimer les dimensions en premier

  3. utilisez awkpour tester le premier nombre (hauteur de l'image) en vous assurant qu'il est supérieur à 500 et s'il s'agit des dimensions d'impression et du nom du fichier, sinon ne faites rien.

h3rrmiller
la source
Merci. J'ai dû faire un léger changement - le $ 1 dans l'argument awk à $ 3. Mais cela m'a définitivement aidé.
steve-er-rino
12
exiftool -q -r -ext png -if '$ImageHeight > 500' -p '$Directory/$FileName' .
Stéphane Chazelas
la source
5

Je pense que quelque chose d'autre que les utilitaires shell serait plus approprié, par exemple 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 );

}

Moins de bavardage en essayant d'analyser 7 $; obtenez directement les dimensions. Oui, vous aurez besoin du module Image :: Info, mais, sur CentOS / RHEL, c'est un package standard, vous pouvez donc simplement exécuter yum install perl-Image-Info.

cjc
la source
1
Bien que perl soit normalement une excellente solution, ce n'est pas le cas, d'autant plus que je n'ai pas Image :: Info ni l'option à installer.
steve-er-rino
1
La solution Perl est un peu plus rapide que celle de find / file / awk, ce qui est bien, et sur les dérivés ubuntu, le module d'informations sur l'image est disponible à partir deapt-get install libimage-info-perl
rivimey
5

Vous pouvez également utiliser identifydepuis ImageMagick:

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

Ou sous OS X:

mdfind 'kMDItemFSName=*.png&&kMDItemPixelHeight>500' -onlyin .
Lri
la source
0
find . -name '*.png' -exec file "{}" \+ | awk -F"(: +PNG image data|,| x )" '$4 > 500 {print $4" "$1}'
tink
la source
ne fonctionne pas: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, transtypez 7 $ en entier avant la comparaison, c'est-à-dire int (7 $)> 500 .. en l'absence de transtypage awk a recours à une comparaison de chaîne littérale
iruvar
Steve, d'où vient ce ","? Mon "fichier" ne produit pas cela. Mais comme Chandra l'a dit: vous pouvez explicitement forcer 7 $ à devenir un entier en utilisant la méthode indiquée dans son commentaire.
tink
votre déclaration awk ne fonctionnera que si le nom de fichier ne contient aucun espace
h3rrmiller
@tink le "," fait partie du fichier renvoyé dans mon environnement.
steve-er-rino
0

Cette solution fonctionnera également. La dernière partie du code ( mv "$img" ./lowpixel) déplacera les fichiers sous une largeur et une hauteur spécifiées vers un dossier. Dans l'exemple suivant, toutes les images jpg inférieures à 300x300 seront déplacées vers un dossier nommé 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

whitewings
la source