1099 votes

Compter récursivement les fichiers dans un répertoire Linux

Comment puis-je compter récursivement les fichiers dans un répertoire Linux ?

J'ai trouvé ça :

find DIR_NAME -type f ¦ wc -l

Mais lorsque je l'exécute, il renvoie l'erreur suivante.

find : les chemins doivent précéder l'expression : ¦

91 votes

Vous confondez la barre cassée ¦ (ASCII 166) avec la barre verticale | (ASCII 124) utilisé pour Pipeline UNIX .

12 votes

@SkippyleGrandGourou Ça ne s'appelle pas un tuyau ?

38 votes

DaveStephens Oui, on l'appelle aussi comme ça. On l'appelle aussi trait de Sheffer, verti-bar, vbar, bâton, ligne verticale, barre verticale, barre, obélisque, glidus.

13voto

Nestor Urquiza Points 81
tree $DIR_PATH | tail -1

Exemple de sortie :

5309 répertoires, 2122 fichiers

9voto

BroSlow Points 3691

Si vous voulez éviter les cas d'erreur, n'autorisez pas les wc -l pour voir les fichiers avec des nouvelles lignes (qu'il comptera comme 2+ fichiers)

Par exemple, considérons le cas d'un fichier unique 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

Depuis au moins gnu wc ne semble pas avoir d'option pour lire/compter une liste à terminaison nulle (sauf depuis un fichier), la solution la plus simple serait de ne pas lui passer les noms de fichiers, mais une sortie statique à chaque fois qu'un 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 soutient

> find -type f -printf '\n' | wc -l
1

5voto

Sophy Points 585

Pour déterminer combien de fichiers il y a dans le répertoire courant, mettez dans ls -1 | wc -l . Cela utilise wc pour faire un comptage du nombre de lignes (-l) dans la sortie de ls -1 . Il ne compte pas les dotfiles. 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 d'une unité au nombre réel. Merci à Kam Nejad pour cette remarque.

Si vous voulez compter uniquement les fichiers et NE PAS inclure les liens symboliques (juste un exemple de ce que vous pourriez faire), vous pourriez utiliser ls -l | grep -v ^l | wc -l (c'est un "L" et non un "1" cette fois, nous voulons une liste "longue" ici). grep vérifie toute ligne commençant par "l" (indiquant un lien), et rejette cette ligne (-v).

Vitesse relative : "ls -1 /usr/bin/ | wc -l" prend environ 1,03 secondes 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

3 votes

ls -l doit faire stat syscall sur chaque fichier pour lire sa taille, mtime et autres propriétés, ce qui est lent. Sur les grands répertoires (100.000+ fichiers), l'exécution de ls -l peut prendre plusieurs minutes. Donc, pour ne compter que les fichiers, utilisez toujours ls -1 | wc -l .

0 votes

Un 486SX25, sympa

0 votes

ls -1 peut encore être lent dans les grands répertoires, car il doit trier les fichiers. Il suffit de consulter printf '%s\n' * fait la même chose, et évite l'extérieur ls (qui est problématique de toute façon) mais la solution la plus efficace est d'utiliser une commande qui n'effectue aucun tri, telle que find . (La sortie glob est triée par le shell).

4voto

nickl- Points 1772

Avec bash :

Créez un tableau d'entrées avec ( ) et obtenez le nombre avec #.

FILES=(./*); echo ${#FILES[@]}

Ok, cela ne compte pas récursivement les fichiers mais je voulais montrer l'option simple en premier. Un cas d'utilisation commun pourrait être la création de sauvegardes de renouvellement d'un fichier. Cela créera logfile.1, logfile.2, logfile.3 etc.

CNT=(./logfile*); mv logfile logfile.${#CNT[@]}

Comptage 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[@]}

4voto

Victoria Stuart Points 21

Pour les répertoires avec des espaces dans le nom ... (basé sur les différentes réponses ci-dessus) -- imprimer récursivement le nom du répertoire avec le nombre de fichiers qu'il contient :

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 du répertoire est mieux visualisée en utilisant 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) est tiré de la réponse 2 à https://unix.stackexchange.com/questions/48492/list-only-regular-files-but-not-directories-in-current-directory

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

Applcation : Je veux trouver le nombre maximum de fichiers parmi plusieurs centaines de répertoires (profondeur = 1) [sortie ci-dessous formatée pour être lisible] :

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 un tri naturel. ... Ainsi, mon nombre maximum de fichiers dans l'un de ces répertoires (Claws Mail) est de 4375 fichiers. Si je tape à gauche ( https://stackoverflow.com/a/55409116/1904943 ) ces noms de fichiers - ils sont tous nommés numériquement, en commençant par le chiffre 1, dans chaque répertoire - et en les complétant jusqu'à 5 chiffres au total, je devrais être tranquille.


Addendum

Trouver le nombre total de fichiers, de 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X