Me gustaría buscar recursivamente un árbol de directorios y enumerar la cantidad de archivos disponibles en cada carpeta que tiene un nombre correspondiente a una cadena determinada. En efecto, me gustaría devolver resultados de:
ls -l | wc -l
para cada carpeta que he identificado a través de find
.
Código
El siguiente código enumera correctamente la cantidad de archivos en cada carpeta cuyo nombre contiene Datos mágicos cadena.
find /path/to/cool/stuff
-maxdepth 4
-type d
-name '*Magic Data*'
-print0 | xargs
--verbose
-0 -I {} ls -l {}
Me gustaría expandirlo y canalizar los resultados de ls
a wc -l
.
Intento
find /path/to/cool/stuff
-maxdepth 4
-type d
-name '*Magic Data*'
-print0 | xargs
--verbose
-0 -I {} ls -l {} | wc -l
Esto falla e imprime:
ls -l /path/to/cool/stuff/some/folders/Magic Data
ls -l /path/to/cool/stuff/some/folders2/Magic Data
Salida deseada
/path/to/cool/stuff/some/folders/Magic Data 29
/path/to/cool/stuff/some/folders2/Magic Data 30
La salida deseada contendría:
- Ruta completa a la carpeta buscada
- Salida de
wc -l
, que en este caso refleja el recuento de archivos no ocultos
Respuesta aceptada:
Hay dos formas principales de resolver esto:
-
Modificar el
find
comando para que solo ingrese a los directorios que le interesan y luego imprima un solo carácter (por ejemplo,x
) para cada archivo encontrado dentro. Luego cuente el número de ese carácter producido conwc -l
. Es más seguro generar un carácter que el nombre de la ruta, ya que los nombres de ruta en Unix podrían contener líneas nuevas. Esta solución es un poco complicada ya que implica usar-prune
para ignorar los directorios que no nos interesan, o alternativamente! -path
. -
Encuentre los directorios tal como lo ha hecho hasta ahora, pero luego use un script en línea para contar los archivos dentro. Esto es más simple y lo que muestro a continuación.
find /path/to/cool/stuff -maxdepth 4 -type d -name "*Magic Data*'
-exec bash -O dotglob -c '
dir=$1
set -- "$dir"/*
printf "%s %dn" "$dir" "$#"' bash {} ';'
Aquí, encontramos los directorios como lo haces tú, luego, para cada directorio, ejecutamos este breve bash
guión:
dir=$1
set -- "$dir"/*
printf "%s %dn" "$dir" "$#"
Esto toma el nombre de ruta del directorio desde la línea de comando (dado por find
), y expande el *
patrón global dentro de él. Configurando el dotglob
shell en la línea de comando para el script, tenemos la garantía de contar también los archivos y directorios ocultos (remove -O dotglob
para no contar los nombres ocultos).
Hacemos la expansión de todos los nombres como argumento para set
, que establecerá los parámetros posicionales para las entradas expandidas. El número de parámetros posicionales está disponible como $#
, que por lo tanto es también el recuento de archivos en ese directorio en particular.
Relacionado:
- Comprender la opción -exec de `find`