Je veux find des files dans un directory et les identifier par leur mimetype, pas par l'extension des files.
J'utilise cette command pour déterminer le type de mime:
% find . -type f -print0 | xargs -0 -I{} file --mime-type {} ./foo bar.png: image/png ./OWoHp.png: image/png ./J7ZwV.png: image/png ./foo.txt: inode/x-empty ./bar: inode/x-empty ./hUXnc.png: image/png
Le premier file a une nouvelle ligne dans le nom de file:
% ls foo$'\n'bar.png foo?bar.png
C'est ok et le file ne devrait pas être renommé.
Avec la command suivante, je veux filterr tous les files qui ne sont pas des images.
% find . -type f -print0 | xargs -0 -I{} file --mime-type {} | awk -F$"\0" -F": " '/image/ {print $1}' bar.png ./OWoHp.png ./J7ZwV.png ./hUXnc.png
et identifier leurs tailles:
% find . -type f -print0 | xargs -0 -I{} file --mime-type {} | awk -F$"\0" -F":" '/image/ {print $1}' | xargs -I{} identify -format "%[fx:w*h] %i\n" {} identify: unable to open image `bar.png': No such file or directory @ error/blob.c/OpenBlob/2709. identify: unable to open file `bar.png' @ error/png.c/ReadPNGImage/3922. 26696 ./OWoHp.png 47275 ./J7ZwV.png 37975 ./hUXnc.png
Mais cela ne fonctionne pas car il n'y a pas de file avec le nom bar.png
. Le nom correct est
./foo bar.png
avec une nouvelle ligne dans le nom.
Vous pouvez utiliser la construction -exec sh -c '...'
avec find
:
find . -type f -exec sh -c 'file --brief --mime-type "$0" | \ grep -q ^image/ && identify -format "%[fx:w*h] %i\n" "$0"' {} \;
ou avec exiftool
:
exiftool -q -if '$mimetype =~ /image/' -p '$megapixels $directory/$filename' -r .
Je pense que votre meilleur pari sera d'utiliser une boucle de shell au lieu de xargs: Vous pouvez alors contrôler comment les commands sont envoyées l'argument de nom de file.
find . -type f -print0 | while IFS= read -rd "" filename; do type=$( file --brief "$filename" ) if [[ $type == *image* ]]; then identify -format "%[fx:w*h] %i\n" "$filename" fi done
Comme le souligne steeldriver, votre problème n'est pas awk
, c'est un file
. Il n'y a pas de NUL dans l'input que vous donnez à awk
car le file
mangé. Je ferais tout cela dans la coquille à la place:
find . -type f -print0 | while IFS= read -r -d '' file; do file --mime-type "$file" | grep -qP "\bimage/" && printf '%s %s\0' $(identify -format '%[fx:w*h]' "$file") "$file"; done | sort -gz | tr '\0' '\n' 256 ./file 10 256 ./file 15 484 ./file 16 576 ./file 11 576 ./file 17 1024 ./file 12 1024 ./file 19 2304 ./file 13 5625 ./file 14 15190 ./file 2 15680 ./file 1 16384 ./file 9 65536 ./file 18 145200 ./file 0 183531 ./file 6 364807 ./file 3 364807 ./file 4 364807 ./file 5 388245 ./file 8 550560 ./file 7
J'ai inclus le sort
puisque je suppose que vous essayez d'améliorer votre réponse ici . L'exemple ci-dessus a été exécuté sur des noms de file avec des espaces et un ( file\n3
avec une nouvelle ligne). Pour une raison quelconque, identify
n'imprimera pas les lignes \0
-terminées, donc j'utilise printf
place.