Comment compter récursivement des fichiers dans un répertoire Linux?
J'ai trouvé ça:
find DIR_NAME -type f ¦ wc -l
Mais quand j'exécute ceci, l'erreur suivante est renvoyée.
trouver: les chemins doivent précéder l'expression:
Cela devrait fonctionner:
find DIR_NAME -type f | wc -l
Explication:
-type f
pour n'inclure que les fichiers.|
(( et non ¦
) redirige la sortie standard de la commande find
vers la sortie standard de la commande wc
.wc
(abréviation de Word count) compte les nouvelles lignes, les mots et les octets dans son entrée ( docs ).-l
pour ne compter que les nouvelles lignes.Notes:
DIR_NAME
par .
pour exécuter la commande dans le dossier actuel.-type f
pour inclure des répertoires (et des liens symboliques) dans le décompte.Expliquez pourquoi votre exemple ne fonctionne pas:
Dans la commande que vous avez montrée, vous n’utilisez pas le "Pipe" (|
) pour relier deux commandes, mais la barre brisée (¦
) que le shell ne reconnaît pas comme une commande ou quelque chose de similaire. C'est pourquoi vous obtenez ce message d'erreur.
Pour le répertoire actuel:
find -type f | wc -l
Si vous souhaitez connaître le nombre de fichiers contenus dans chaque répertoire de votre répertoire actuel:
for i in */ .*/ ; do
echo -n $i": " ;
(find "$i" -type f | wc -l) ;
done
Cela peut bien sûr aller sur une seule ligne. La parenthèse clarifie la sortie dont wc -l
est censé regarder (find $i -type f
dans ce cas).
Vous pouvez utiliser
$ tree
après avoir installé le paquet tree avec
$ Sudo apt-get install tree
(sur une machine Linux Debian/Mint/Ubuntu).
La commande affiche non seulement le nombre de fichiers, mais également le nombre de répertoires séparément. L'option -L peut être utilisée pour spécifier le niveau d'affichage maximal (qui, par défaut, correspond à la profondeur maximale de l'arborescence de répertoires).
Les fichiers cachés peuvent également être inclus en fournissant l'option -a
.
Sur mon ordinateur, rsync
est un peu plus rapide que find | wc -l
dans la réponse acceptée. Par exemple, vous pouvez compter les fichiers dans /Users/joe/
comme ceci:
[joe:~] $ rsync --stats --dry-run -ax /Users/joe/ /xxx
Number of files: 173076
Number of files transferred: 150481
Total file size: 8414946241 bytes
Total transferred file size: 8414932602 bytes
La deuxième ligne contient le nombre de fichiers, 150 481 dans l'exemple ci-dessus. En bonus, vous obtenez également la taille totale (en octets).
Remarques:
--dry-run
(ou -n
en abrégé) est importante pour ne pas transférer les fichiers!/xxx
peut être n'importe quel dossier vide ou non existant. N'utilisez pas /
ici.-x
pour "ne pas dépasser les limites du système de fichiers", ce qui signifie que si vous l'exécutez pour /
et que vous avez des disques durs externes connectés, il ne compte que les fichiers de la partition racine.Comme les noms de fichiers sous UNIX peuvent contenir des nouvelles lignes (oui, des nouvelles lignes), wc -l
peut compter trop de fichiers. Je voudrais imprimer un point pour chaque fichier, puis compter les points:
find DIR_NAME -type f -printf "." | wc -c
En combinant plusieurs des réponses, la solution la plus utile semble être:
find . -maxdepth 1 -type d -print0 |
xargs -0 -I {} sh -c 'echo -e $(find "{}" -printf "\n" | wc -l) "{}"' |
sort -n
Il peut gérer des choses étranges telles que les noms de fichiers qui incluent des espaces, des parenthèses et même de nouvelles lignes. Il trie également la sortie en fonction du nombre de fichiers.
Vous pouvez augmenter le nombre après -maxdepth
pour obtenir également le décompte des sous-répertoires. N'oubliez pas que cela peut potentiellement prendre beaucoup de temps, en particulier si vous avez une structure de répertoire hautement imbriquée en combinaison avec un nombre élevé -maxdepth
.
Si vous voulez savoir combien de fichiers et de sous-répertoires existent dans le répertoire de travail actuel, vous pouvez utiliser cette ligne unique.
find . -maxdepth 1 -type d -print0 | xargs -0 -I {} sh -c 'echo -e $(find {} | wc -l) {}' | sort -n
Cela fonctionnera dans la version GNU et omettez simplement le -e de la commande echo pour Linux sous BSD (par exemple, OSX).
Si vous voulez éviter les erreurs, n'autorisez pas wc -l
à voir les fichiers avec des nouvelles lignes (qui compteront comme plus de 2 fichiers)
par exemple. Prenons un cas où nous avons un seul fichier contenant un seul caractère EOL
> mkdir emptydir && cd emptydir
> touch $'file with EOL(\n) character in it'
> find -type f
./file with EOL(?) character in it
> find -type f | wc -l
2
Puisque au moins gnu wc
ne semble pas avoir l’option de lire/compter une liste terminée par un zéro (sauf à partir d’un fichier), la solution la plus simple consisterait simplement à ne pas lui donner de nom de fichier, mais une sortie statique à chaque fois. le fichier est trouvé, par exemple dans le même répertoire que ci-dessus
> find -type f -exec printf '\n' \; | wc -l
1
Ou si votre find
le supporte
> find -type f -printf '\n' | wc -l
1
Vous pouvez utiliser la commande ncdu
. Il comptera de manière récursive le nombre de fichiers qu'un répertoire Linux contient. Voici un exemple de sortie:
Il a une barre de progression, ce qui est pratique si vous avez plusieurs fichiers:
Pour l'installer sur Ubuntu:
Sudo apt-get install -y ncdu
Indice de référence: J'ai utilisé https://archive.org/details/cv_corpus_v1.tar (380390 fichiers, 11 Go) comme dossier dans lequel il faut compter le nombre de fichiers.
find . -type f | wc -l
: environ 1m20 à compléterncdu
: environ 1m20 à complétertree $DIR_PATH | tail -1
Exemple de sortie:
5309 répertoires, 2122 fichiers
Pour déterminer le nombre de fichiers présents dans le répertoire en cours, entrez ls -1 | wc -l
. Ceci utilise wc
pour compter le nombre de lignes (-l)
dans la sortie de ls -1
. Cela ne compte pas les fichiers de points. Veuillez noter que ls -l
(c'est un "L" plutôt qu'un "1" comme dans les exemples précédents) que j'ai utilisé dans les versions précédentes de ce HOWTO vous donnera en fait un nombre de fichiers supérieur de un au nombre réel. Merci à Kam Nejad pour ce point.
Si vous voulez compter uniquement les fichiers et NE PAS inclure de liens symboliques (juste un exemple de ce que vous pourriez faire d'autre), vous pouvez utiliser ls -l | grep -v ^l | wc -l
(c'est un "L" et non un "1", nous voulons un " longue "liste ici). grep
recherche toutes les lignes commençant par "l" (indiquant un lien) et les supprime (-v).
Vitesse relative: "ls -1/usr/bin/| wc -l" prend environ 1,03 seconde sur un 486SX25 non chargé (/ usr/bin/sur cette machine contient 355 fichiers). "ls -l /usr/bin/ | grep -v ^l | wc -l
" prend environ 1,19 seconde.
Source: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x700.html
Si vous avez besoin de compter un type de fichier spécifique récursivement , vous pouvez effectuer les opérations suivantes:
find YOUR_PATH -name '*.html' -type f | wc -l
-l
est juste pour afficher le nombre de lignes dans la sortie.
Avec bash:
Créez un tableau d'entrées avec () et obtenez le nombre avec #.
FILES=(./*); echo ${#FILES[@]}
Ok, ça ne compte pas récursivement les fichiers mais je voulais d'abord montrer l'option simple. Un cas d'utilisation courant pourrait être la création de sauvegardes par survol d'un fichier. Cela créera logfile.1, logfile.2, logfile.3 etc.
CNT=(./logfile*); mv logfile logfile.${#CNT[@]}
Nombre récursif avec bash 4+ globstar
activé (comme mentionné par @tripleee)
FILES=(**/*); echo ${#FILES[@]}
Pour obtenir le nombre de fichiers de manière récursive, nous pouvons toujours utiliser find de la même manière.
FILES=(`find . -type f`); echo ${#FILES[@]}
Pour les répertoires avec des espaces dans le nom ... (en fonction des diverses réponses ci-dessus) - Affiche récursivement le nom du répertoire avec le nombre de fichiers dans:
find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done
Exemple (formaté pour la lisibilité):
pwd
/mnt/Vancouver/Programming/scripts/claws/corpus
ls -l
total 8
drwxr-xr-x 2 victoria victoria 4096 Mar 28 15:02 'Catabolism - Autophagy; Phagosomes; Mitophagy'
drwxr-xr-x 3 victoria victoria 4096 Mar 29 16:04 'Catabolism - Lysosomes'
ls 'Catabolism - Autophagy; Phagosomes; Mitophagy'/ | wc -l
138
## 2 dir (one with 28 files; other with 1 file):
ls 'Catabolism - Lysosomes'/ | wc -l
29
La structure des répertoires est mieux visualisée avec tree
:
tree -L 3 -F .
.
├── Catabolism - Autophagy; Phagosomes; Mitophagy/
│ ├── 1
│ ├── 10
│ ├── [ ... SNIP! (138 files, total) ... ]
│ ├── 98
│ └── 99
└── Catabolism - Lysosomes/
├── 1
├── 10
├── [ ... SNIP! (28 files, total) ... ]
├── 8
├── 9
└── aaa/
└── bbb
3 directories, 167 files
man find | grep mindep
-mindepth levels
Do not apply any tests or actions at levels less than levels
(a non-negative integer). -mindepth 1 means process all files
except the starting-points.
ls -p | grep -v /
(utilisé ci-dessous) provient de la réponse 2 à l'adresse https://unix.stackexchange.com/questions/48492/list-only-regular-files-but-not-directories-in-current- répertoire
find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done
./Catabolism - Autophagy; Phagosomes; Mitophagy: 138
./Catabolism - Lysosomes: 28
./Catabolism - Lysosomes/aaa: 1
Application: Je souhaite trouver le nombre maximal de fichiers sur plusieurs centaines de répertoires (toute la profondeur = 1) [la sortie ci-dessous est à nouveau formatée pour la lisibilité]:
date; pwd
Fri Mar 29 20:08:08 PDT 2019
/home/victoria/Mail/2_RESEARCH - NEWS
time find . -mindepth 1 -type d -print0 | while IFS= read -r -d '' i ; do echo -n $i": " ; ls -p "$i" | grep -v / | wc -l ; done > ../../aaa
0:00.03
[victoria@victoria 2_RESEARCH - NEWS]$ head -n5 ../../aaa
./RNA - Exosomes: 26
./Cellular Signaling - Receptors: 213
./Catabolism - Autophagy; Phagosomes; Mitophagy: 138
./Stress - Physiological, Cellular - General: 261
./Ancient DNA; Ancient Protein: 34
[victoria@victoria 2_RESEARCH - NEWS]$ sed -r 's/(^.*): ([0-9]{1,8}$)/\2: \1/g' ../../aaa | sort -V | (head; echo ''; tail)
0: ./Genomics - Gene Drive
1: ./Causality; Causal Relationships
1: ./Cloning
1: ./GenMAPP 2
1: ./Pathway Interaction Database
1: ./Wasps
2: ./Cellular Signaling - Ras-MAPK Pathway
2: ./Cell Death - Ferroptosis
2: ./Diet - Apples
2: ./Environment - Waste Management
988: ./Genomics - PPM (Personalized & Precision Medicine)
1113: ./Microbes - Pathogens, Parasites
1418: ./Health - Female
1420: ./Immunity, Inflammation - General
1522: ./Science, Research - Miscellaneous
1797: ./Genomics
1910: ./Neuroscience, Neurobiology
2740: ./Genomics - Functional
3943: ./Cancer
4375: ./Health - Disease
sort -V
est une sorte naturelle. ... Ainsi, mon nombre maximal de fichiers dans l'un de ces répertoires (Claws Mail) est de 4375 fichiers. Si je quitte le pavé gauche ( https://stackoverflow.com/a/55409116/190494 ) ces noms de fichiers - ils sont nommés numériquement, en commençant par 1, dans chaque répertoire - et en pointant jusqu'à 5 nombre total de chiffres, ça devrait aller.
Addendum
Trouvez le nombre total de fichiers, sous-répertoires dans un répertoire.
$ date; pwd
Tue 14 May 2019 04:08:31 PM PDT
/home/victoria/Mail/2_RESEARCH - NEWS
$ ls | head; echo; ls | tail
Acoustics
Ageing
Ageing - Calorie (Dietary) Restriction
Ageing - Senescence
Agriculture, Aquaculture, Fisheries
Ancient DNA; Ancient Protein
Anthropology, Archaeology
Ants
Archaeology
ARO-Relevant Literature, News
Transcriptome - CAGE
Transcriptome - FISSEQ
Transcriptome - RNA-seq
Translational Science, Medicine
Transposons
USACEHR-Relevant Literature
Vaccines
Vision, Eyes, Sight
Wasps
Women in Science, Medicine
$ find . -type f | wc -l
70214 ## files
$ find . -type d | wc -l
417 ## subdirectories
J'ai écrit ffcnt pour accélérer le comptage de fichiers récursif dans des circonstances spécifiques: disques en rotation et systèmes de fichiers prenant en charge le mappage d'étendue.
Cela peut être un ordre de grandeur plus rapide que les approches basées sur ls
ou find
, mais YMMV.
Il y a beaucoup de réponses correctes ici. En voici un autre!
find . -type f | sort | uniq -w 10 -c
où .
est le dossier dans lequel rechercher et 10
est le nombre de caractères permettant de grouper le répertoire.