una - listar directorios y subdirectorios linux
Encuentra el nĂºmero de archivos en un directorio (8)
Creo que puedes tener más control sobre esto usando find
:
find <path> -maxdepth 1 -type f -printf "." | wc -c
-
find -maxdepth 1
no profundizará en la jerarquía de archivos. -
-type f
permite filtrar solo archivos. Del mismo modo, puede utilizar-type d
para directorios. -
-printf "."
imprime un punto para cada partido. -
wc -c
cuenta los caracteres, por lo que cuenta los puntos creados por laprint
... lo que significa contar cuántos archivos existen en la ruta dada.
¿Hay algún método en Linux para calcular el número de archivos en un directorio (es decir, hijos inmediatos) en O (1) (independientemente del número de archivos) sin tener que listar primero el directorio? Si no es O (1), ¿existe una forma razonablemente eficiente?
Estoy buscando una alternativa a ls | wc -l
ls | wc -l
.
La opción -U
para ls
no está en POSIX, y en ls
OS X tiene un significado diferente a GNU ls
, que es que hace que -t
y -l
utilicen los tiempos de creación en lugar de los tiempos de modificación. -f
está en POSIX como una extensión XSI. El manual de GNU ls
describe -f
como do not sort, enable -aU, disable -ls --color
y -U
como do not sort; list entries in directory order
do not sort; list entries in directory order
.
POSIX describe -f
así:
Obliga a que cada argumento se interprete como un directorio y enumera el nombre que se encuentra en cada espacio. Esta opción desactivará
-l
,-t
,-s
y-r
, y activará-a
; el orden es el orden en que aparecen las entradas en el directorio.
Los comandos como ls|wc -l
dan el resultado incorrecto cuando los nombres de archivo contienen nuevas líneas.
En zsh puedes hacer algo como esto:
a=(*(DN));echo ${#a}
D
( glob_dots
) incluye archivos cuyo nombre comienza con un punto y N
( null_glob
) hace que el comando no null_glob
un error en un directorio vacío.
O lo mismo en bash:
shopt -s dotglob nullglob;a=(*);echo ${#a[@]}
Si IFS
contiene dígitos ASCII, agregue comillas dobles alrededor de ${#a[@]}
. Agregue shopt -u failglob
para asegurarse de que el failglob
esté configurado.
Una opción portátil es usar find
:
find . ! -name . -prune|grep -c /
grep -c /
puede reemplazarse con wc -l
si los nombres de archivo no contienen nuevas líneas. ! -name . -prune
! -name . -prune
es una alternativa portátil a -mindepth 1 -maxdepth 1
.
O aquí hay otra alternativa que generalmente no incluye archivos cuyo nombre comience con un punto:
set -- *;[ -e "$1" ]&&echo "$#"
Sin embargo, el comando anterior incluye archivos cuyo nombre comienza con un período cuando se establece una opción como dotglob
en bash o glob_dots
en zsh. Cuando *
no coincide con ningún archivo, el comando produce un error en zsh con la configuración predeterminada.
Para el número de todos los archivos en un directorio actual, intente esto:
ls -lR * | wc -l
Que yo sepa, no hay mejor alternativa. Esta información puede ser ajena al tema de esta pregunta y es posible que ya sepa que en Linux (en general en Unix) los directorios son solo un archivo especial que contiene la lista de otros archivos (entiendo que los detalles exactos dependerán de un archivo específico) sistema pero esta es la idea general). Y no hay ninguna llamada para encontrar el número total de entradas sin recorrer toda la lista. Por favor, hazme correcto si estoy equivocado.
Readdir no es tan caro como puede pensar. La habilidad es evitar la estadística de cada archivo, y (opcionalmente) ordenar la salida de ls.
/bin/ls -1U | wc -l
evita los alias en su shell, no ordena la salida, y enumera 1 archivo por línea (no es estrictamente necesario al canalizar la salida en wc).
La pregunta original se puede reformular como "¿la estructura de datos de un directorio almacena un conteo del número de entradas?", Para lo cual la respuesta es no. No hay una forma más eficiente de contar los archivos que readdir (2) / getdents (2).
Uno puede obtener el número de subdirectorios de un directorio dado sin atravesar la lista completa mediante estadísticas (stat (1) o stat (2)) del directorio dado y observando el número de enlaces a ese directorio. Un directorio dado con N directorios secundarios tendrá un número de enlaces de N + 2, un enlace para la entrada ".." de cada subdirectorio, más dos para el "." y ".." entradas del directorio dado.
Sin embargo, no se puede obtener el número de todos los archivos (ya sean archivos regulares o subdirectorios) sin recorrer toda la lista, eso es correcto.
Sin embargo, el comando "/ bin / ls -1U" no obtendrá todas las entradas. Solo obtendrá las entradas de directorio que no comiencen con el carácter de punto (.). Por ejemplo, no contaría el archivo ".profile" que se encuentra en muchos directorios de inicio de sesión $ HOME.
Se puede usar el comando "/ bin / ls -f" o el comando "/ bin / ls -Ua" para evitar la clasificación y obtener todas las entradas.
Quizás desafortunadamente para sus propósitos, el comando "/ bin / ls -f" o el comando "/ bin / ls -Ua" también contarán el "." y ".." entradas que están en cada directorio. Deberá restar 2 del conteo para evitar contar estas dos entradas, como en el siguiente:
expr `/bin/ls -f | wc -l` - 2 # Those are back ticks, not single quotes.
La opción --format = single-column (-1) no es necesaria en el comando "/ bin / ls -Ua" cuando se canaliza la salida de "ls", como en "wc" en este caso. El comando "ls" escribirá automáticamente su salida en una sola columna si la salida no es un terminal.
Utilicé este comando ... funciona como un encanto ... solo para cambiar el maxdepth ... eso es subdirectorios
find * -maxdepth 0 -type d -exec sh -c "echo -n {} '' '' ; ls -lR {} | wc -l" /;
usar ls -1 | wc -l