Recibo el siguiente error cuando intento acceder a ls *.txt | wc -l
un directorio que contiene muchos archivos:
-bash: /bin/ls: Argument list too long
¿El umbral de esta "Lista de argumentos" depende de la distribución o de las especificaciones de la computadora? Por lo general, canalizaría el resultado de un resultado tan grande a otros comandos ( wc -l
por ejemplo), por lo que no me preocupan los límites del terminal.
ls
, lo cual es una mala idea, así que mejor evítelo. Para contar, vea ¿Cuál es la mejor manera de contar la cantidad de archivos en un directorio? , para una solución alternativa difícil, ¿por qué for loop no genera un error de "argumento demasiado largo"? .Respuestas:
La lista de argumentos de su mensaje de error demasiado larga proviene del * de
ls *.txt
.Este límite es una seguridad tanto para los programas binarios como para su Kernel. Verá en esta página más información al respecto, y cómo se usa y calcula.
No existe tal límite en el tamaño de la tubería. Entonces simplemente puede emitir este comando:
NB: En Linux moderno, los caracteres extraños en los nombres de archivo (como las nuevas líneas) se escaparán con herramientas como
ls
ofind
, pero aún se mostrarán desde * . Si está en un Unix antiguo, necesitará este comandoNB2: Me preguntaba cómo se puede crear un archivo con una nueva línea en su nombre. No es tan difícil, una vez que sabes el truco:
fuente
-maxdepth 1
si no tiene la intención de contar archivos en subdirectorios.-exec echo \;
.find
. Enfind
OS X y en los sistemas basados en busybox, y supongo que cualquier sistema basado en BSD muestra el nombre del archivo con una nueva línea, lo que alteraría el conteo.wc -l
está contando nuevas líneas. Por eso queremos que tenga nuevas líneas.Depende principalmente de su versión del kernel de Linux.
Debería poder ver el límite de su sistema ejecutando
que le indica el número máximo de bytes que puede tener una línea de comando después de ser expandida por el shell.
En Linux <2.6.23, el límite suele ser de 128 KB.
En Linux> = 2.6.25, el límite es 128 KB o 1/4 del tamaño de su pila (ver
ulimit -s
), el que sea mayor.Consulte la página del comando man execve (2) para obtener todos los detalles.
Desafortunadamente, las tuberías
ls *.txt
no van a solucionar el problema, porque el límite está en el sistema operativo, no en el shell.El shell expande el
*.txt
, luego intenta llamary tiene tantos archivos
*.txt
que coinciden que excede el límite de 128 KB.Tendrás que hacer algo como
en lugar.
(Y vea los comentarios de Shawn J. Goff a continuación sobre los nombres de archivos que contienen nuevas líneas).
fuente
.
y qué-maxdepth 1
en la última línea? ¡Gracias! : D.
significa directorio actual,-maxdepth 1
significa que no se ve en subdirectorios. Esto estaba destinado a coincidir con los mismos archivos que*.txt
.Otra solución alternativa:
Aunque
ls
produce más resultados que los quels *.txt
produce (o intenta producir), no se encuentra con el problema de "argumento demasiado largo", porque no le está pasando ningún argumentols
. Tenga en cuenta quegrep
toma una expresión regular en lugar de un patrón de coincidencia de archivos.Es posible que desee utilizar:
(suponiendo que su versión de
ls
soporte esta opción). Esto le indica quels
no clasifique su salida, lo que podría ahorrar tiempo y memoria, y en este caso el orden no importa, ya que solo está contando archivos. Los recursos dedicados a ordenar la salida generalmente no son significativos, pero en este caso ya sabemos que tiene una gran cantidad de*.txt
archivos.Y debe considerar reorganizar sus archivos para que no tenga tantos en un solo directorio. Esto puede o no ser factible.
fuente
MAX_ARG_PAGES parece ser un parámetro del núcleo. Usar
find
yxargs
es una combinación típica para abordar este límite, pero no estoy seguro de que funcionewc
.Canalizar la salida de
find . -name \*\.txt
un archivo y contar las líneas en ese archivo debería servir como solución alternativa.fuente
ls
la salida de, no resolverá esto. Mientras el comodín * .txt se expanda por encima del límite, fallará incluso antes de comenzarls
y generar cualquier salida.ls
, debe especificar-maxdepth 1
evitar escanear recursivamente los subdirectorios.Esto puede estar sucio pero funciona para mis necesidades y dentro de mi competencia. No creo que funcione muy rápido, pero me permitió seguir con mi día.
Estaba obteniendo una larga lista de 90,000 jpgs y los canalizaba a avconv para generar un lapso de tiempo.
Anteriormente estaba usando ls * .jpg | avconv antes de encontrarme con este problema.
fuente