Tengo un directorio con una gran cantidad de archivos. No veo un ls
interruptor para proporcionar el recuento. ¿Hay alguna magia de línea de comandos para obtener un recuento de archivos?
fuente
Tengo un directorio con una gran cantidad de archivos. No veo un ls
interruptor para proporcionar el recuento. ¿Hay alguna magia de línea de comandos para obtener un recuento de archivos?
Usando una definición amplia de "archivo"
ls | wc -l
(tenga en cuenta que no cuenta los archivos ocultos y supone que los nombres de los archivos no contienen caracteres de nueva línea).
Para incluir archivos ocultos (excepto .
y ..
) y evitar problemas con los caracteres de nueva línea, la forma canónica es:
find . ! -name . -prune -print | grep -c /
O recursivamente:
find .//. ! -name . -print | grep -c //
wc
es un programa de "conteo de palabras". El -l
cambio hace que cuente líneas. En este caso, cuenta las líneas en la salida de ls
. Esta es siempre la forma en que me enseñaron a obtener un recuento de archivos para un directorio determinado, también.
ls
lo hace ls -1
si la salida es una pipa.
ls -la
, obtendrá tres líneas en el directorio. Desea ls -lA | wc -l
omitir las entradas .
y ..
. Sin embargo, seguirás siendo uno por uno.
ls -q | wc -l
aunque tenga en cuenta que este enfoque todavía no contará los archivos ocultos, y que los directorios se contarán.
Para una definición estrecha de archivo:
find . -maxdepth 1 -type f | wc -l
-maxdepth 1
recuento de archivos de forma recursiva (o ajustarlo para la profundidad de búsqueda máxima deseada).
find -maxdepth 1 -type f -printf "\n" | wc -l
ls -1 | wc -l
...
$ ls --help | grep -- ' -1'
-1 list one file per line
...
$ wc --help | grep -- ' -l'
-l, --lines print the newline counts
PD: Nota ls - <número-> | wc - <letter-l>
ls
hacer -1
automáticamente cuando la salida es a una tubería.
[[ -p /dev/stdin ]] && echo "stdin is from a pipe"
Probablemente la respuesta más completa usando ls
/ wc
pair es
ls -Aq | wc -l
si desea contar archivos de puntos y
ls -q | wc -l
de otra manera.
-A
es contar archivos de puntos, pero omite .
y ..
.-q
hacer ls
reemplazar caracteres no gráficos, específicamente caracteres de nueva línea, con ?
, haciendo que la salida sea 1 línea para cada archivoPara obtener una salida de una línea desde el ls
terminal (es decir, sin conectarlo wc
), -1
se debe agregar la opción.
(comportamiento de ls
probado con coreutils 8.23)
-1
no es necesario. En cuanto a "maneja las nuevas líneas de los nombres de archivos de manera sensata con la salida de la consola" , esto se debe al -q
interruptor (que debe usar en lugar de -b
porque es portátil) que "obliga a escribir cada instancia de caracteres de nombre de archivo no imprimibles y caracteres <tab> como el carácter <question-mark> ('?'). Las implementaciones pueden proporcionar esta opción por defecto si la salida es a un dispositivo terminal ". Así por ejemplo, ls -Aq | wc -l
para contar todos los archivos / directorios o ls -qp | grep -c /
para contar directorios único no ocultos, etc ...
-b
a -q
.
Si sabe que el directorio actual contiene al menos un archivo no oculto:
set -- *; echo "$#"
Esto es obviamente generalizable a cualquier glob.
En un guión, esto tiene el efecto secundario a veces desafortunado de sobrescribir los parámetros posicionales. Puede solucionarlo utilizando una subshell o con una función (versión Bourne / POSIX) como:
count_words () {
eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"
Una solución alternativa es $(ls -d -- * | wc -l)
. Si el glob es *
, el comando se puede acortar a $(ls | wc -l)
. Analizar la salida de ls
siempre me hace sentir incómodo, pero aquí debería funcionar siempre y cuando los nombres de los archivos no contengan nuevas líneas o ls
se les escapen. Y $(ls -d -- * 2>/dev/null | wc -l)
tiene la ventaja de manejar el caso de un globo no coincidente con gracia (es decir, devuelve 0 en ese caso, mientras que el set *
método requiere pruebas complejas si el globo puede estar vacío).
Si los nombres de archivo pueden contener caracteres de nueva línea, se debe utilizar una alternativa $(ls -d ./* | grep -c /)
.
Cualquiera de esas soluciones que se basan en pasar la expansión de un globo ls
puede fallar con un error de lista de argumentos demasiado largo si hay muchos archivos coincidentes.
local
o eliminarla: eval $1=$#
o simplemente usar echo $#
y hacer number_of_files=$(count_words *)
.
$#
(no lo habías hecho antes de la edición)?
$1
. Entonces, lo que quiero contar es la cantidad de parámetros que no son el primer parámetro. (No puedo usar shift
porque necesito mantener el nombre de la variable.) (Umm, ahora si hubieras preguntado por la primera línea ...)
shift
si es el momento adecuado.
He encontrado du --inodes
útil, pero no estoy seguro de qué versión du
requiere. Debería ser sustancialmente más rápido que los enfoques alternativos que utilizan find
y wc
.
En Ubuntu 17.10, funciona lo siguiente:
du --inodes # all files and subdirectories
du --inodes -s # summary
du --inodes -d 2 # depth 2 at most
Combinar con | sort -nr
para ordenar descendente por número de inodos que contienen.
Si usamos ls / wc pair si estamos agregando -U, será mucho más rápido (no ordenar).
ls -AqU | wc -l
-U
Sin embargo, es específico de GNU.
Después de instalar el comando del árbol, simplemente escriba:
tree
Si también quieres archivos ocultos:
tree -a
Si está utilizando Debian / Mint / Ubuntu Linux, escriba el siguiente comando para instalar el comando del árbol:
sudo apt-get install tree
La opción -L se usa para especificar el nivel máximo de visualización del árbol de directorios. El comando de árbol no solo cuenta la cantidad de archivos, sino también la cantidad de directorios, considerando tantos niveles del árbol de directorios como desee.
find -maxdepth 1 -type f -printf . | wc -c
-maxdepth 1
lo hará no recursivo, find
es recursivo por defecto-type f
incluirá solo archivos-printf .
Es un lindo toque. imprime un punto para cada archivo en lugar del nombre de archivo, y ahora puede manejar cualquier nombre de archivo y también guarda datos; solo tenemos que contar los puntos :)| wc -c
cuenta personajesSin tubería, sin copia de cadena, sin tenedor, simplemente golpea un forro
$ fcount() { local f i=0; for f in *; do let i++; done; echo $i; }; fcount
Aquí hay otra técnica similar a la que publicó Gilles :
word_count () { local c=("$@"); echo "${#c[@]}"; }
file_count=$(word_count *)
que crea una matriz con 13,923 elementos (si esa es la cantidad de archivos que hay).
c
matriz? word_count() { echo "$#"; }
seria suficiente. El objetivo de la solución @Gilles es almacenar el recuento en una variable devuelta para evitar tener que usar la sustitución de comandos (que implica una bifurcación y una tubería en capas diferentes a ksh93).
find . -type f -maxdepth 1 | wc -l
Esto puede enumerar solo los archivos en el directorio actual.
find . -type f
encontrará archivos en el directorio actual y también, recursivamente, en subdirectorios.
Prueba esto, espero que esta respuesta te ayude
echo $((`ls -l | wc -l` -1 ))
Puedes consultar con:
ls -l | grep -v ^l | wc -l
Mejorando algunas respuestas dadas antes pero esta vez haciendo explícitamente.
$ tree -L 1 | tail -n 1 | cut -d " " -f 3
Vale la pena notar el uso de algunos comandos amados como tail
y cut
. Además, tenga en cuenta que el árbol no está disponible de forma predeterminada. El comando anterior captura primero la información sobre el directorio en el nivel 1, luego obtiene la última línea tail -n 1
donde está nuestro objetivo y termina cut
tomando la tercera palabra.
Por ejemplo, ubicando en /
:
/ $ tree -L 1
.
├── 1
├── bin -> usr/bin
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── lost+found
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── srv
├── sys
├── tmp
├── usr
└── var
20 directories, 1 file
/ $ tree -L 1 | tail -n 1
20 directories, 1 file
/ $ tree -L 1 | tail -n 1 | cut -d " " -f 3
1
Entonces, ¿qué hay de preguntar el número de directorios?
En Linux, para hacer que el comando sea muy robusto y manejar archivos que pueden tener nuevas líneas en su nombre, use esto:
find -maxdepth 1 -type f -print0 | tr -cd '\0' | wc -c
Esto nos salva de la terrible experiencia de analizar la ls
salida.
Relacionado:
Usa el tree
comando, solo:
tree
tree . | tail
otree -a . | tail
incluir archivos / directorios ocultos,tree
es recursivo si eso es lo que quieres.