Estoy tratando de averiguar qué módulos use Test::Version
en cpan. Así que he usado minicpan
para reflejarlo. Mi problema es que necesito iterar a través de los archivos que se descargan y grep los archivos que están en los archivos. ¿Alguien puede decirme cómo puedo hacer esto? preferiblemente de una manera que me diga qué archivo en el archivo y en qué línea está.
(nota:no todos son tarballs, algunos son archivos zip)
Respuesta aceptada:
Ok, apliquemos la filosofía de Unix. ¿Cuáles son los componentes de esta tarea?
- Búsqueda de texto:necesita una herramienta para buscar texto en un archivo, como
grep
. - Recursivo:necesita una herramienta para buscar archivos en un árbol de directorios, como
find
. - Archivos:necesitas una herramienta para leerlos.
La mayoría de los programas de Unix operan en archivos. Entonces, para operar fácilmente en los componentes de archivo, debe acceder a ellos como archivos, en otras palabras, debe acceder a ellos como directorios.
El sistema de archivos AVFS presenta una vista del sistema de archivos donde cada archivo de almacenamiento /path/to/foo.zip
es accesible como un directorio ~/.avfs/path/to/foo/zip#
. AVFS proporciona acceso de solo lectura a los formatos de archivo de almacenamiento más comunes.
mountavfs
find ~/.avfs"$PWD" ( -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' )
-exec sh -c '
find "$0#" -name "*.pm" -exec grep "$1" {} +
' {} 'Test::Version' ;
fusermount -u ~/.avfs # optional
Explicaciones:
- Monte el sistema de archivos AVFS.
- Busque los archivos de almacenamiento en
~/.avfs$PWD
, que es la vista AVFS del directorio actual. - Para cada archivo, ejecute el fragmento de shell especificado (con
$0
=nombre del archivo y$1
=patrón a buscar). $0#
es la vista de directorio del archivo$0
.{}
en lugar de{}
es necesario en caso de que elfind
externo sustituye{}
dentro de-exec ;
argumentos (algunos lo hacen, otros no).- Opcional:finalmente desmonte el sistema de archivos AVFS.
O en zsh ≥4.3:
mountavfs
grep 'Test::Version' ~/.avfs$PWD/**/*.(tgz|tar.gz|zip)(e''
reply=($REPLY#/**/*.pm(.N))
'')
Explicaciones:
~/.avfs$PWD/**/*.(tgz|tar.gz|zip)
coincide con los archivos en la vista AVFS del directorio actual y sus subdirectorios.PATTERN(e''CODE'')
aplica CÓDIGO a cada coincidencia de PATRÓN. El nombre del archivo coincidente está en$REPLY
. Configuración de lareply
matriz convierte la coincidencia en una lista de nombres.$REPLY#
es la vista de directorio del archivo.$REPLY#/**/*.pm
coincide con.pm
archivos en el archivo.- El
N
El calificador global hace que el patrón se expanda a una lista vacía si no hay ninguna coincidencia.