Je voudrais une commande BASH pour lister seulement le nombre de fichiers dans chaque sous-répertoire d'un répertoire.
Par exemple, dans le répertoire /tmp
il y a dir1
, dir2
, ... J'aimerais voir :
`dir1` : x files
`dir2` : x files ...
Je voudrais une commande BASH pour lister seulement le nombre de fichiers dans chaque sous-répertoire d'un répertoire.
Par exemple, dans le répertoire /tmp
il y a dir1
, dir2
, ... J'aimerais voir :
`dir1` : x files
`dir2` : x files ...
Vous pouvez utiliser ce code Python. Démarrez l'interpréteur en exécutant python3
et collez ceci :
folder_path = '.'
import os, glob
for folder in sorted(glob.glob('{}/*'.format(folder_path))):
print('{:}: {:>8,}'.format(os.path.split(folder)[-1], len(glob.glob('{}/*'.format(folder)))))
Ou une version récursive pour les comptages imbriqués :
import os, glob
def nested_count(folder_path, level=0):
for folder in sorted(glob.glob('{}/'.format(os.path.join(folder_path, '*')))):
print('{:}{:}: {:,}'.format(' '*level, os.path.split(os.path.split(folder)[-2])[-1], len(glob.glob(os.path.join(folder, '*')))))
nested_count(folder, level+1)
nested_count('.')
Exemple de sortie :
>>> figures: 5
>>> misc: 1
>>> notebooks: 5
>>> archive: 65
>>> html: 12
>>> py: 12
>>> src: 14
>>> reports: 1
>>> content: 6
>>> src: 1
>>> html_download: 1
Pour des méthodes fiables de comptage des fichiers dans un répertoire, voir ma réponse : Quel est un code fiable pour compter les fichiers ?
Dans votre cas, nous devons en plus itérer sur les sous-répertoires. A for
La boucle est bonne pour cela :
for d in */; do
c="$(cd -- "$d" && find . ! -name . -exec printf a \; | wc -c)"
if [ "$?" -ne 0 ]; then c="?"; fi
printf '%-25s : %s\n' "${d%/}" "$c"
done
Notes :
Normalement */
ne correspond pas aux répertoires dont le nom commence par un point (répertoires "cachés"). En Bash shopt -s dotglob
change ça.
! -name .
est responsable de ne pas compter le sous-répertoire respectif lui-même.
${d%/}
supprime la queue /
. Si nous avons utilisé *
au lieu de */
dans le for
il n'y aurait alors rien à supprimer, mais la boucle itèrerait également sur les non-répertoires.
Double tiret ( --
) est utile dans le cas où un nom commence par -
. Si nous avons utilisé ./*/
dans le for
alors il n'y aurait pas besoin de --
mais vous voudrez probablement supprimer le début de l'expression ./
tout en imprimant la sortie, cela compliquerait le code.
Dans la sortie ?
apparaît en cas de problème. Défaillant cd
(probablement en raison de permissions insuffisantes) est le problème que j'avais en tête. find
L'impossibilité de descendre dans un (sous- )sous-répertoire ne constitue pas un problème dans ce contexte. Si vous voyez un numéro, cela signifie find
a trouvé autant de fichiers là, donc il y a au moins autant de fichiers dans le répertoire. Si vous voyez ?
alors cela signifie find
n'a probablement pas couru parce que cd
avait échoué.
Voir le réponse déjà liée il vous aidera à adapter le find
à vos besoins (par exemple, solution non récursive, comptage des fichiers d'un type spécifique, certaines optimisations).
Les caractères multi-octets dans les noms prêtent à confusion printf
et la sortie peut sembler mal alignée.
Le format qui imprime les noms est %-25s
Ainsi, tout nom est imprimé tel quel (avec un remplissage). Les caractères de nouvelle ligne, les caractères de retour chariot, les séquences d'échappement dans les noms peuvent provoquer des résultats inattendus. Avec printf
builtin dans l'utilisation de Bash %q
au lieu de %s
(il sera %-25q
dans notre cas) pour atténuer le problème.
Ce que j'utilise... Ceci fait un tableau de tous les sous-répertoires dans celui que vous donnez en paramètre. Imprime le sous-répertoire et le nombre de ce même sous-répertoire jusqu'à ce que tous les sous-répertoires soient traités.
#!/bin/bash
directories=($(/bin/ls -l $1 | /bin/grep "^d" | /usr/bin/awk -F" " '{print $9}'))
for item in ${directories[*]}
do
if [ -d "$1$item" ]; then
echo "$1$item"
/bin/ls $1$item | /usr/bin/wc -l
fi
done
SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.