Dans le but de tester, j'aimerais compter le nombre de fichiers d'images dans un répertoire, séparant chaque type de fichier image par extension de fichier (jpg = "oui". Ceci parce que plus tard, il sera utile pour un autre script qui exécutera une action sur chaque extension de fichier). Puis-je utiliser quelque chose comme ce qui suit pour seuls les fichiers JPEG?
jpg=""
count=`ls -1 *.jpg 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo jpg files found: $count ; jpg="yes"
fi
Considérant les extensions de fichiers JPG, PNG, BMP, RAW et d'autres, devrais-je utiliser un cycle while
pour le faire?
Je suggérerais une approche différente, en évitant les éventuels problèmes de division de mots de ls
#!/bin/bash
shopt -s nullglob
for ext in jpg png gif; do
files=( *."$ext" )
printf 'number of %s files: %d\n' "$ext" "${#files[@]}"
# now we can loop over all the files having the current extension
for f in "${files[@]}"; do
# anything else you like with these files
:
done
done
Vous pouvez boucler sur le tableau files
avec des autres commandes que vous souhaitez effectuer sur les fichiers de chaque extension.
Plus de manière significative - ou pour des coquilles qui ne fournissent pas des tableaux explicitement - vous pouvez réutiliser le tableau de paramètres de position de Shell I.e.
set -- *."$ext"
puis remplacer ${#files[@]}
et ${files[@]}
avec $#
et "$@"
Mon approche serait:
Une sorte de comme ceci (dernier awk
appel est purement pour la mise en forme):
ls -q -U | awk -F . '{print $NF}' | sort | uniq -c | awk '{print $2,$1}'
(en supposant =GNU ls
ici pour le -U
Option pour sauter le tri comme optimisation. Il peut être supprimé en toute sécurité sans affecter la fonctionnalité s'il n'est pas pris en charge).
Cela traverse récursivement des fichiers et compte des extensions correspondant à:
$ find . -type f | sed -e 's/.*\.//' | sort | uniq -c | sort -n | grep -Ei '(tiff|bmp|jpeg|jpg|png|gif)$'
6 tiff
7 bmp
26 jpeg
38 gif
51 jpg
54 png
find -type f | sed -e 's/.*\.//' | sort | uniq -c
Tout ce qui implique ls
est susceptible de produire des résultats inattendus avec des caractères spéciaux (espace et autres symboles). Toute bashism (comme des tableaux comme) n'est pas portable. Tout ce qui implique while read
est généralement lent.
D'autre part, find
est très flexible (beaucoup d'options à filtrer), il a [au moins] deux syntaxes qui échouent sans danger pour les caractères spéciaux ... et il échoue bien sur le grand répertoire.
Pour cet exemple, j'ai utilisé -iname
Pour correspondre à un nom d'extension majuscule et minuscule. J'ai aussi limité le -maxdepth 1
Pour respecter votre question "dans le répertoire actuel" de votre question. Plutôt que de compter le nombre de lignes, où les noms de fichiers pourraient inclure CR/LF, -print0
Imprimera un octet nul à la fin de chaque nom de fichier ... alors | tr -d -c "\000" | wc -l
Comptez avec précision des fichiers (NULL BYTES!).
extensions="jpg png gif"
for ext in $extensions; do
c=$(find . -maxdepth 1 -iname "*.$ext" -print0 | tr -d -c "\000" | wc -c)
if [ $c -gt 0 ]; then
echo "Found $c *.$ext files"
find . -maxdepth 1 -iname "*.$ext" -print0 | xargs -0 -r -n1 DOSOMETHINGHERE
# or # find . -maxdepth 1 -iname "*.$ext" -exec "ls" "-l" "{}" ";"
fi
done
P.s. -print0 | tr -d -c "\000" | wc -c
peut être remplacé par -printf "\000" | wc -c
ou même -printf '\n' | wc -l
.
Peut-être qu'il peut devenir plus court
exts=( *.jpg *.png *.gif ); printf "There are ${#exts[@]}" extensions;
Je voulais juste obtenir le total:
find ./ -type f | sed -e 's/.*\.//' | uniq -c | sort -u | awk '{print $1}' | awk '{total = total + $1}END{print total}'
sortir:
2347623
peut simplement utiliser ls pour quelque chose de ce simple imo
ls -l /opt/ssl/certs/*.pem | wc -l
ou
count=$(ls -l /some/folder/*.jpg | wc -l)
ou
ls *.{mp3,exe,mp4} 2>/dev/null | wc -l
Si vous êtes sûr de l'extension, vous pouvez aller avec find
comme
find *.jpeg | wc -l