web-dev-qa-db-fra.com

Trouver le nombre de fichiers correspondant à un modèle dans un répertoire sous Linux

Je suis nouveau sur Linux. J'ai un répertoire sous Linux avec environ 250 000 fichiers dont j'ai besoin pour trouver le nombre de fichiers correspondant à un modèle.

J'ai essayé d'utiliser la commande suivante:

ls -1 20061101-20131101_kh5x7tte9n_2010_* | wc -l

J'ai reçu le message d'erreur suivant:

-bash: /bin/ls: Argument list too long
0

Veuillez aider. Merci d'avance

20
db1

Il peut être préférable d'utiliser find pour cela:

find . -name "pattern_*" -printf '.' | wc -l

Dans votre cas particulier:

find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_2010_*" -printf '.' | wc -m

find renverra une liste de fichiers correspondant aux critères. -maxdepth 1 fera la recherche à faire juste dans le chemin, pas de sous-répertoires ( merci Petesh! ). -printf '.' imprimera un point pour chaque correspondance, de sorte que les noms avec de nouvelles lignes ne feront pas wc -m Pause.

Alors wc -m indiquera le nombre de caractères qui correspondra au nombre de fichiers.


Comparaison des performances de deux options possibles:

Créons 10 000 fichiers avec ce modèle:

$ for i in {1..10000}; do touch 20061101-20131101_kh5x7tte9n_201_$i; done

Et comparez ensuite le temps nécessaire pour obtenir le résultat avec ls -1 ... ou find ...:

$ time find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_201_*" | wc -l
10000

real    0m0.034s
user    0m0.017s
sys     0m0.021s

$ time ls -1 | grep 20061101-20131101_kh5x7tte9n_201 | wc -l
10000

real    0m0.254s
user    0m0.245s
sys     0m0.020s

find est x5 fois plus rapide! Mais si nous utilisons ls -1f ( merci encore Petesh! ), alors ls est encore plus rapide que find:

$ time ls -1f | grep 20061101-20131101_kh5x7tte9n_201 | wc -l
10000

real    0m0.023s
user    0m0.020s
sys     0m0.012s
43
fedorqui

Essaye ça:

ls -1 | grep 20061101-20131101_kh5x7tte9n_2010_ | wc -l
2
Dale

vous avez un "argument trop long" car Shell étend votre modèle à la liste des fichiers. essayer:

find  -maxdepth 1 -name '20061101-20131101_kh5x7tte9n_2010_*' |wc -l

veuillez faire attention - le modèle est placé entre guillemets pour empêcher l'expansion de Shell

2
Odobenus Rosmarus

Vous devriez généralement éviter ls dans les scripts et en fait, effectuer le calcul dans une fonction Shell évitera l'erreur "liste d'arguments trop longue" car il n'y a pas de exec frontière et donc le ARGV_MAX la limite n'entre pas en jeu.

number_of_files () {
    if [ -e "$1" ]; then
        echo "$#"
    else
        echo 0
    fi
}

Les protections conditionnelles contre la globalisation ne sont pas développées du tout (ce qui est le défaut par défaut; dans Bash, vous pouvez shopt -s nullglob pour que les caractères génériques qui ne correspondent à aucun fichier soient développés dans la chaîne vide).

Essayez-le:

number_of_files 20061101-20131101_kh5x7tte9n_2010_*
1
tripleee