web-dev-qa-db-fra.com

Rechercher des images supérieures à une résolution spécifique dans un répertoire Linux

Ceci est une question complémentaire de ma précédente question posée ici . Je dois trouver et consigner le chemin d'accès à toutes les images jpeg situées dans des sous-répertoires avec une résolution supérieure à un nombre spécifique (par exemple, supérieure à 800 en largeur).

Eh bien, il y a des millions d'images et je me demande pourquoi le processus find ci-dessous est si lent. J'ai donc besoin d'optimiser le script bash pour le rendre plus rapide:

find -type f -regex "^.*\.\(png\|jpg\|jpeg\)$" -exec identify -format "%d/%f, %w, %h\n" {} \; | awk -F ',' '$2 > 800 && $3 > 600'

Mais il y a une caractéristique intéressante: j'ai 4 répertoires principaux (1 à 4), chacun avec 256 sous-répertoires. Chacun de ces sous-répertoires contient environ 5 000 sous-sous-répertoires, chacun contenant environ 10 images. Donc, cela ressemble à major_dir/subdir/subsubdir/10.jpg. La caractéristique intéressante est que toutes les images de ces sous-sous-répertoires ont la même résolution. donc je n'ai pas vraiment besoin de traiter toutes ces 10 images. Si la résolution de l'un d'entre eux est satisfaisante, il ne me reste plus qu'à consigner un seul chemin (le chemin du sous-sous-répertoire). Avec ça, j'espère avoir une vitesse 10x plus rapide. Et en plus, toutes mes images sont .jpg si cela aide aussi.

Comment puis-je faire cela en script bash? Donc, une sortie idéale ressemblerait à ceci (path, width_of_images_there, height)

/path/to/sub_dir1, 1600, 1200
/path/to/sub_dir2, 1600, 1200
/path/to/sub_dir3, 3200, 2400
/path/to/sub_dir4, 1000, 800
3
Tina J

Que diriez-vous de cela:

find /path/to/dir_with_major_dirs -path "*/*/*/*.jpg" -type f -exec bash -c '
  for i; do
    [[ "$p" = "${i%/*}" ]] || identify -format "%d, %w, %h\n" "$i"
    p="${i%/*}"
  done' _ {} + |
awk -F ',' '$2 > 800 && $3 > 600'

Ce test pour chaque fichier jpg trouvé si son chemin correspond au chemin du fichier précédent et uniquement s’il ne fonctionne pas identify. La sortie est dirigée vers awk comme vous l'avez déjà compris, je viens de retirer /%f de la commande identify pour supprimer le nom de fichier inutile.

2
dessert