regex - expresiones - Encuentra el número de archivos que coinciden con un patrón en un directorio en Linux
sed expresiones regulares (5)
Soy nuevo en Linux. Tengo un directorio en Linux con aproximadamente 250,000 archivos que necesito para encontrar el número de archivos que coinciden con un patrón.
Intenté usar el siguiente comando:
ls -1 20061101-20131101_kh5x7tte9n_2010_* | wc -l
Recibí el siguiente mensaje de error:
-bash: /bin/ls: Argument list too long
0
Por favor ayuda. Gracias por adelantado
Podría ser mejor usar find
para esto:
find . -name "pattern_*" -printf ''.'' | wc -l
En su caso específico:
find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_2010_*" -printf ''.'' | wc -l
find
devolverá una lista de archivos que coinciden con los criterios. -maxdepth 1
hará que la búsqueda se realice solo en la ruta, sin subdirectorios ( gracias Petesh! ). -printf ''.''
imprimirá un punto para cada coincidencia, de modo que los nombres con nuevas líneas no harán que wc -l
rompa.
Entonces wc -l
indicará el número de líneas.
Comparación de rendimiento de dos opciones posibles:
Vamos a crear 10 000 archivos con este patrón:
$ for i in {1..10000}; do touch 20061101-20131101_kh5x7tte9n_201_$i; done
Y luego compare el tiempo que lleva obtener el resultado con ls -1 ...
o find ...
:
$ time find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_201_*" | wc -l
10000
real 0m0.034s
user 0m0.017s
sys 0m0.021s
$ time ls -1 | grep 20061101-20131101_kh5x7tte9n_201 | wc -l
10000
real 0m0.254s
user 0m0.245s
sys 0m0.020s
find
es x5 veces más rápido! Pero si usamos ls -1f
(¡ gracias Petesh otra vez! ), Entonces ls
es incluso más rápido que find
:
$ time ls -1f | grep 20061101-20131101_kh5x7tte9n_201 | wc -l
10000
real 0m0.023s
user 0m0.020s
sys 0m0.012s
Por lo general, debe evitar ls
en los scripts y, de hecho, realizar el cálculo en una función de shell evitará el error de "lista de argumentos demasiado larga" porque no hay un límite exec
y por lo tanto el límite ARGV_MAX
no entra en juego.
number_of_files () {
if [ -e "$1" ]; then
echo "$#"
else
echo 0
fi
}
Las protecciones condicionales contra el globo no se expanden en absoluto (que es la shopt -s nullglob
predeterminada fuera de la caja; en Bash, puede shopt -s nullglob
para hacer comodines que no coincidan con ningún archivo expandido en la cadena vacía).
Intentalo:
number_of_files 20061101-20131101_kh5x7tte9n_2010_*
Prueba esto:
ls -1 | grep 20061101-20131101_kh5x7tte9n_2010_ | wc -l
tienes un "argumento demasiado largo" porque el shell expande tu patrón a la lista de archivos. tratar:
find -maxdepth 1 -name ''20061101-20131101_kh5x7tte9n_2010_*'' |wc -l
preste atención: el patrón se incluye entre comillas para evitar la expansión de la carcasa
ls -1 | grep ''20061101-20131101_kh5x7tte9n_2010_*'' | wc -l
La respuesta anterior no incluía citas sobre criterios de búsqueda ni * comodín.