L'erreur suivante s'affiche lorsque j'essaie de créer ls *.txt | wc -l
un répertoire contenant de nombreux fichiers:
-bash: /bin/ls: Argument list too long
Le seuil de cette "liste d'arguments" dépend-il de la distribution ou des spécifications de l'ordinateur? Habituellement, je transmettrais le résultat d'un résultat aussi important à d'autres commandes ( wc -l
par exemple), de sorte que les limites du terminal ne me concernent pas.
ls
, ce qui est une mauvaise idée, alors mieux vaut l’éviter. Pour compter, voir Quelle est la meilleure façon de compter le nombre de fichiers dans un répertoire? , pour une solution de contournement délicate, voyez pourquoi la boucle for ne soulève pas l’erreur “argument too long”? .Réponses:
Votre liste d'arguments de message d'erreur trop longue provient du * de
ls *.txt
.Cette limite est une sécurité pour les programmes binaires et votre noyau. Vous verrez sur cette page plus d'informations à ce sujet, ainsi que son utilisation et son calcul.
Il n'y a pas de telle limite sur la taille du tuyau. Vous pouvez donc simplement lancer cette commande:
NB: Sous Linux moderne, les caractères étranges dans les noms de fichiers (comme les nouvelles lignes) seront échappés avec des outils tels que
ls
oufind
, mais toujours affichés à partir de * . Si vous utilisez un ancien Unix, vous aurez besoin de cette commandeNB2: Je me demandais comment créer un fichier avec une nouvelle ligne dans son nom. Ce n'est pas si difficile, une fois que vous connaissez le truc:
la source
-maxdepth 1
si vous n’avez pas l’intention de compter les fichiers dans les sous-répertoires.-exec echo \;
.find
. Lefind
sur OS X et sur les systèmes busybox, et je suppose que tout système basé sur BSD affiche le nom du fichier avec une nouvelle ligne, ce qui gâcherait le nombre.wc -l
compte les nouvelles lignes. Nous voulons donc qu'il y ait de nouvelles lignes.Cela dépend principalement de votre version du noyau Linux.
Vous devriez pouvoir voir la limite de votre système en lançant
qui vous indique le nombre maximal d'octets qu'une ligne de commande peut avoir après avoir été développée par le shell.
Sous Linux <2.6.23, la limite est généralement de 128 Ko.
Sous Linux> = 2.6.25, la limite est 128 Ko ou 1/4 de la taille de votre pile (voir
ulimit -s
), selon la valeur la plus grande.Voir la page de manuel execve (2) pour tous les détails.
Malheureusement, la tuyauterie
ls *.txt
ne résoudra pas le problème, car la limite se trouve dans le système d'exploitation, pas dans le shell.Le shell développe le
*.txt
, puis essaie d'appeleret vous avez tellement de fichiers correspondants
*.txt
que vous dépassez la limite de 128 Ko.Vous devrez faire quelque chose comme
au lieu.
(Et voir ci-dessous les commentaires de Shawn J. Goff sur les noms de fichiers contenant des nouvelles lignes.)
la source
.
et la-maxdepth 1
moyenne dans la dernière ligne? Merci! : D.
signifie répertoire courant,-maxdepth 1
signifie qu'il ne recherche pas dans les sous-répertoires. Cela devait correspondre aux mêmes fichiers que*.txt
.Une autre solution de contournement:
Même si la
ls
sortie est supérieure à lals *.txt
production (ou aux tentatives de production), elle ne rencontre pas le problème "argument trop long", car vous ne transmettez aucun argument àls
. Notez quegrep
prend une expression régulière plutôt qu'un modèle de correspondance de fichier.Vous voudrez peut-être utiliser:
(en supposant que votre version de
ls
supporte cette option). Cela vous dit dels
ne pas trier sa sortie, ce qui pourrait vous faire gagner du temps et de la mémoire - et dans ce cas, l'ordre n'a pas d'importance, car vous ne comptez que des fichiers. Les ressources consacrées au tri de la sortie ne sont généralement pas importantes, mais dans ce cas, nous savons déjà que vous avez un très grand nombre de*.txt
fichiers.Et vous devriez envisager de réorganiser vos fichiers afin de ne pas en avoir autant dans un seul répertoire. Cela peut être possible ou non.
la source
MAX_ARG_PAGES semble être un paramètre du noyau. Utiliser
find
etxargs
est une combinaison typique pour traiter cette limite, mais je ne suis pas sûr que cela fonctionnewc
.Transférer la sortie de
find . -name \*\.txt
dans un fichier et compter les lignes de ce fichier doit servir de solution de contournement.la source
ls
la sortie de, cela ne résoudra pas ce problème. Tant que le caractère générique * .txt dépasse la limite, il échouera avant même de commencerls
et de générer une sortie.ls
vous devez spécifier-maxdepth 1
pour éviter d'analyser de manière récursive les sous-répertoires.Cela peut être sale, mais cela fonctionne pour mes besoins et dans les limites de mes compétences. Je ne pense pas que cela fonctionne très vite, mais cela m'a permis de continuer ma journée.
Je recevais une longue liste de 90 000 jpgs et les transmettais à avconv pour générer un timelapse.
J'utilisais auparavant ls * .jpg | avconv avant que je rencontre ce problème.
la source