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
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" -- .
--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 agrep Bourne
si estás buscando scripts bash ogrep Perl
si estaba buscando scripts en Perl o algo por el estilo.