2008-09-02 15 views
30

Tengo que obtener una lista de directorio que contiene alrededor de 2 millones de archivos, pero cuando hago un comando ls nada vuelve. He esperado 3 horas. He intentado ls | tee directory.txt, pero parece que cuelgue para siempre.comando ls rápido

Supongo que el servidor está haciendo una gran cantidad de clasificación de inode. ¿Hay alguna forma de acelerar el comando ls para obtener una lista de directorios de nombres de archivos? No me importa el tamaño, las fechas, el permiso o similares en este momento.

Respuesta

1

¿Qué tal find ./ -type f (que encontrará todos los archivos en el directorio actual)? Quítate el -type f para encontrar todo.

+0

Esto sería encontrar archivos en el directorio actual, y también en cualquier subdirectorio. – mwfearnley

10

Trate de usar:

find . -type f -maxdepth 1 

Esto sólo aparecerá una lista de archivos en el directorio, dejar de lado el argumento -type f si desea una lista de archivos y directorios.

1

cosas para probar:

Verificar ls no es alias?

alias ls 

¿Tal vez intente buscar en su lugar?

find . \(-type d -name . -prune \) -o \(-type f -print \) 

Espero que esto ayude.

3

Puede redirigir la salida y ejecutar el proceso ls en segundo plano.

ls > myls.txt & 

Esto le permitiría continuar con su negocio mientras está en funcionamiento. No bloquearía tu caparazón.

No estoy seguro de qué opciones hay para ejecutar ls y recuperar menos datos. Siempre puede ejecutar man ls para verificar.

2

Supongo que está utilizando GNU ls? tratar

\ls 

Será unalias ls habituales (ls -color = Auto).

+0

Cierto, colorear es el culpable habitual para mí: cuando se colorea, 'ls' intenta determinar el tipo y el modo de cada entrada de directorio, lo que da como resultado muchas llamadas' stat (2) ', por lo tanto, cargas de actividad de disco. – Ruslan

33
ls -U 

hará la ls sin ordenar.

+1

¿Sabes si 'ls -U | sort' es más rápido que' ls'? – User1

+1

No lo sé. Lo dudo, porque sort no puede completar hasta que se hayan visto todos los registros, ya sea que se haga en un programa separado en 'ls'. Pero la única manera de descubrirlo es probarlo. –

+3

Nota: en algunos sistemas, 'ls -f' es equivalente a' ls -aU'; es decir, incluya _todos_ archivos (incluso aquellos cuyos nombres comiencen con '.') y no los clasifique. Y en algunos sistemas, '-f' es *** la opción *** para suprimir la clasificación, y' -U' hace algo más (o nada). – Scott

0

¿Qué tipo de partición estás usando?

Tener millones de archivos pequeños en un directorio podría ser una buena idea usar JFS o ReiserFS que tienen un mejor rendimiento con muchos archivos de pequeño tamaño.

0

Debe proporcionar información sobre qué sistema operativo y el tipo de sistema de archivos está utilizando. En ciertos sabores de UNIX y ciertos sistemas de archivos, es posible que pueda usar los comandos ff y ncheck como alternativas.

2

Si un proceso "no vuelve", recomiendo strace para analizar cómo un proceso está interactuando con el sistema operativo.

En caso de ls:

$strace ls 

que habría visto que se lea todas las entradas de directorio (getdents(2)) antes de que realmente da salida a nada. (Clasificación ... como ya se mencionó aquí)

-1

Un montón de otras buenas soluciones aquí, pero en aras de la exhaustividad:

echo * 
+3

Con 2 millones de archivos, es probable que solo devuelva un error de "línea de comando demasiado larga". – richq

-2

También puede hacer uso de xargs. Solo pipe la salida de ls a través de xargs.

ls | xargs 

Si eso no funciona y el encontrar ejemplos anteriores no funcionan, pruebe a llevarlas por xargs ya que puede ayudar el uso de memoria que podrían ser la causa de sus problemas.

1

Algunos de seguimiento: No mencionas en qué SO estás ejecutando, lo que ayudaría a indicar qué versión de ls estás usando. Esto probablemente no es una pregunta 'bash' tanto como una pregunta ls. Supongo que estás usando GNU ls, que tiene algunas características que son útiles en algunos contextos, pero te matan en grandes directorios.

GNU ls Tratando de tener arreglos más bonitos de columnas. GNU ls intenta hacer un arreglo inteligente de todos los nombres de archivo. En un gran directorio, esto llevará tiempo y memoria.

Para 'arreglar' esto, se puede probar:

ls -1 # no hay columnas en toda

encontrar un lugar BSD ls, http://www.freebsd.org/cgi/cvsweb.cgi/src/bin/ls/ y el uso que en sus directorios grandes.

utilizar otras herramientas, tales como Buscar

4

Esto probablemente no es una respuesta útil, pero si usted no tiene find que puede ser capaz de arreglárselas con tar

$ tar cvf /dev/null . 

Me dicen por personas mayores que yo que, "en el pasado", los entornos de recuperación y usuario único eran mucho más limitados de lo que son hoy en día. De ahí viene este truco.

2

Esta sería la opción más rápida AFAIK: ls -1 -f.

  • -1 (No hay columnas)
  • -f (No clasificado)
0

Hay varias maneras de obtener una lista de archivos:

Use este comando para obtener una lista sin ordenar:

ls -U 

o envíe la lista de archivos a un archivo por usted Sing:

ls /Folder/path > ~/Desktop/List.txt 
4

usando

ls -1 -f 

es aproximadamente 10 veces más rápido y es fácil de hacer (I probado con 1 millón de archivos, pero mi problema original tenía 6 800 000 000 archivos)

Pero en mi caso necesitaba verificar si algún directorio específico contiene más de 10 000 archivos. Si hay más de 10 000 archivos, ya no me interesa cuántos archivos hay. Acabo de salir del programa para que funcione más rápido y no intente leer el resto uno a uno. Si hay menos de 10 000, imprimiré la cantidad exacta. La velocidad de mi programa es bastante similar a ls -1 -f si especifica un valor mayor para el parámetro que la cantidad de archivos.

Puede usar mi find_if_more.pl programa en el directorio actual escribiendo:

find_if_more.pl 999999999 

Si está interesado solamente si hay más de n archivos, escritura terminará más rápido que ls -1 -f con muy gran cantidad de archivos

#!/usr/bin/perl 
    use warnings; 
    my ($maxcount) = @ARGV; 
    my $dir = '.'; 
    $filecount = 0; 
    if (not defined $maxcount) { 
     die "Need maxcount\n"; 
    } 
    opendir(DIR, $dir) or die $!; 
    while (my $file = readdir(DIR)) { 
     $filecount = $filecount + 1; 
     last if $filecount> $maxcount 
    } 
    print $filecount; 
    closedir(DIR); 
    exit 0; 
3

Esta pregunta parece ser interesante y estaba revisando varias respuestas que se publicaron. Para comprender la eficacia de las respuestas publicadas, las ejecuté en 2 millones de archivos y encontré los resultados como a continuación.

$ time tar cvf /dev/null . &> /tmp/file-count 

real 37m16.553s 
user 0m11.525s 
sys  0m41.291s 

------------------------------------------------------ 

$ time echo ./* &> /tmp/file-count 

real 0m50.808s 
user 0m49.291s 
sys  0m1.404s 

------------------------------------------------------ 

$ time ls &> /tmp/file-count 

real 0m42.167s 
user 0m40.323s 
sys  0m1.648s 

------------------------------------------------------ 

$ time find . &> /tmp/file-count 

real 0m2.738s 
user 0m1.044s 
sys  0m1.684s 

------------------------------------------------------ 

$ time ls -U &> /tmp/file-count 

real 0m2.494s 
user 0m0.848s 
sys  0m1.452s 


------------------------------------------------------ 

$ time ls -f &> /tmp/file-count 

real 0m2.313s 
user 0m0.856s 
sys  0m1.448s 

------------------------------------------------------ 

para resumir los resultados

  1. ls -f comando corrió un poco más rápido que ls -U. Deshabilitar el color podría haber causado esta mejora.
  2. find comando corrió en tercer lugar con una velocidad promedio de 2.738 segundos.
  3. Correr solo ls tomó 42.16 segundos. Aquí en mi sistema ls es un alias para ls --color=auto
  4. El uso de la función de expansión de la carcasa con echo ./* funcionó durante 50.80 segundos.
  5. Y la solución basada en tar tomó aproximadamente 37 miuntes.

Todas las pruebas se realizaron por separado cuando el sistema estaba en ralentí.

Una cosa importante a tener en cuenta aquí es que las listas de archivos no se imprimen en el terminal en lugar de fueron redirigidos a un archivo y el conteo de archivos se calculó más tarde con el comando wc. Los comandos se ejecutaron demasiado lento si las salidas se imprimieron en la pantalla.

¿Alguna idea de por qué sucede esto?

3

tengo un directorio con 4 millones de archivos en ella y la única forma que tiene ls escupir archivos de forma inmediata y sin mucha rotación, primero fue

ls -1U 
+0

¡Salvó mi día! ¡Gracias! – dschu

Cuestiones relacionadas