¿Cómo encontrar archivos por tipo de archivo?

Sé que puedo encontrar archivos usando find: find . -type f -name "sunrise" . Resultado de ejemplo:

./sunrise ./events/sunrise ./astronomy/sunrise ./schedule/sunrise 

También sé que puedo determinar el tipo de archivo de un archivo: file sunrise. Resultado de ejemplo:

sunrise: PEM RSA private key 

Pero, ¿cómo puedo encontrar archivos por tipo de archivo?

Por ejemplo, my-find . -type f -name "sunrise" -filetype=bash-script:

./astronomy/sunrise ./schedule/sunrise 

Comentarios

  • No hay --filetype para el comando de búsqueda o cualquier otra cosa que le diga el tipo de archivo. Lo único que puedes hacer es usar --exec file {} \; y luego canalizarlo a grep Bourne si estás buscando scripts bash o grep Perl si estaba buscando scripts en Perl o algo por el estilo.

Responder

«Tipos de archivos» en un sistema Unix son cosas como archivos normales, directorios, canalizaciones con nombre, archivos especiales de caracteres, enlaces simbólicos, etc. Estos son el tipo de archivos que find puede filtrar con su opción -type.

La find no puede por sí sola distinguir entre un «script de shell», «archivo de imagen JPEG» o cualquier otro tipo de archivo normal . Sin embargo, estos tipos de datos se pueden distinguir por la utilidad file, que analiza firmas particulares dentro de los archivos para determinar su tipo.

Una forma común de etiquetar los diferentes tipos de archivos de datos son por su tipo MIME , y file puede determinar el tipo MIME de un archivo.


Usando file con find para detectar el tipo MIME de archivos regulares y usarlo para buscar solo scripts de shell:

find . -type f -exec sh -c " case $( file -bi "$1" ) in */x-shellscript*) exit 0 esac exit 1" sh {} ";" -print 

o, usando bash,

find . -type f \ -exec bash -c "[[ "$( file -bi "$1" )" == */x-shellscript* ]]" bash {} ";" \ -print 

Añada -name sunrise antes de -exec si solo desea detectar scripts con ese nombre.

El comando find de arriba encontrará todos los archivos normales dentro o debajo del directorio actual, y para cada uno de esos archivos, llame a un breve script de shell en línea. Esta secuencia de comandos ejecuta file -bi en el archivo encontrado y sale con un estado de salida cero si la salida de ese comando contiene la cadena /x-shellscript. Si la salida no contiene esa cadena, sale con un estado de salida distinto de cero que hace que find continúe inmediatamente con el siguiente archivo. Si se encontró que el archivo era un script de shell, el comando find procederá a generar el nombre de ruta del archivo (el -print en el end, que también podría ser reemplazado por alguna otra acción).

El comando file -bi generará el tipo MIME del archivo. Para un script de shell en Linux ( y la mayoría de los otros sistemas), esto sería algo así como

text/x-shellscript; charset=us-ascii 

en sistemas con una variante un poco más antigua de file, puede ser

application/x-shellscript 

El bit común es la /x-shellscript subcadena.

Tenga en cuenta que en macOS, tendría que usar file -bI en lugar de file -bi por razones (el -i opción hace algo bastante diferente). La salida en macOS es similar a la de un sistema Linux.


¿Le gustaría realizar alguna acción personalizada en cada script de shell encontrado, puede hacer lo at con otro -exec en lugar del -print en los find comandos anteriores, pero también sería posible hacer

find . -type f -exec sh -c " for pathname do case $( file -bi "$pathname" ) in */x-shellscript*) ;; *) continue esac # some code here that acts on "$pathname" done" sh {} + 

o, con bash,

find . -type f -exec bash -c " for pathname do [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue # some code here that acts on "$pathname" done" bash {} + 

Relacionado:

Responder

Puede ejecutar find en cada archivo encontrado y luego grep para el resultado que le interesa.

# When looking for ASCII Text find . -type -exec file {} \; | grep "ASCII" # or for MS Word Documents find . -type f -exec file {} \; | grep "Microsoft Word" 

Sugiero que el patrón de búsqueda se acerque lo más posible a sus expectativas para mantener el número de las coincidencias falsas positivas son bajas.

Tenga en cuenta que los archivos con nuevas líneas en sus nombres de archivo pueden causar problemas con este enfoque.

Respuesta

Usando perl» s File::LibMagic módulo:

perl -MFile::LibMagic=:easy -MFile::Find -le " find sub { print $File::Find::name if $_ eq "sunrise" and -f and MagicFile$_ eq "PEM RSA private key" }, @ARGV" -- . 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *