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
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
Essaye ça:
ls -1 | grep 20061101-20131101_kh5x7tte9n_2010_ | wc -l
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
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_*