user4556274 a déjà répondu au pourquoi . Ma réponse ne sert qu'à fournir des informations supplémentaires sur la façon de compter correctement les fichiers.
Dans la communauté Unix, le consensus général est que l' analyse de la sortie de ls
est une très très mauvaise idée , car les noms de fichiers peuvent contenir des caractères de contrôle ou des caractères cachés. Par exemple, en raison d'un caractère de nouvelle ligne dans un nom de fichier, nous avons ls | wc -l
dit qu'il y a 5 lignes dans la sortie de ls
(ce qu'il a), mais en réalité il n'y a que 4 fichiers dans le répertoire.
$> touch FILE$'\n'NAME
$> ls
file1.txt file2.txt file3.txt FILE?NAME
$> ls | wc -l
5
Méthode # 1: trouver l'utilitaire
La find
commande, qui est généralement utilisée pour contourner les noms de fichiers, peut nous aider ici en imprimant le numéro d'inode . Qu'il s'agisse d'un répertoire ou d'un fichier, il n'a qu'un seul numéro d'inode unique. Ainsi, en utilisant -printf "%i\n"
et en excluant .
via, -not -name "."
nous pouvons avoir un décompte précis des fichiers. (Notez l'utilisation de -maxdepth 1
pour empêcher la descente récursive dans les sous-répertoires)
$> find -maxdepth 1 -not -name "." -print
./file2.txt
./file1.txt
./FILE?NAME
./file3.txt
$> find -maxdepth 1 -not -name "." -printf "%i\n" | wc -l
4
Méthode n ° 2: globstar
Manière simple, rapide et surtout portable:
$ set -- *
$ echo $#
228
set
La commande est utilisée pour définir les paramètres positionnels du shell (les $<INTEGER>
variables, comme dans echo $1
). Ceci est souvent utilisé pour contourner la /bin/sh
limitation des tableaux manquants. Une version qui effectue des vérifications supplémentaires peut être trouvée dans la réponse de Gille sur Unix et Linux.
Dans les shells qui prennent en charge les tableaux, tels que bash
, nous pouvons utiliser
items=( dir/* )
echo ${#items[@]}
comme proposé par Steeldriver dans les commentaires .
Astuce similaire à la find
méthode utilisée wc
et globstar peut être utilisé avec stat
pour compter les numéros d'inode par ligne:
$> LC_ALL=C stat ./* --printf "%i\n" | wc -l
4
Une autre approche consiste à utiliser un caractère générique en for
boucle. (Remarque, ce test utilise un répertoire différent pour tester si cette approche descend dans les sous-répertoires, ce qu'elle ne fait pas - 16 est le nombre vérifié d'éléments dans my ~/bin
)
$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1
16
Méthode n ° 3: autres langues / interprètes
Python peut également traiter les noms de fichiers problématiques en imprimant la longueur d'une liste étant donné ma os.listdir()
fonction (qui est non récursive, et ne listera que les éléments du répertoire donnés en argument).
$> python -c "import os ; print os.listdir('.')"
['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt']
$> python -c "import os ; print(len(os.listdir('.')))"
4
Voir également
ls | wc -l
échouera s'il y a des fichiers avec une nouvelle ligne dans le nom de fichier. C'est plus résistant:find . -mindepth 1 -maxdepth 1 -printf . | wc -c