(Adaptado de ¿Cómo busco recursivamente archivos comprimidos? )
Instale AVFS , un sistema de archivos que proporciona acceso transparente dentro de los archivos. Primero ejecute este comando una vez para configurar una vista del sistema de archivos de su máquina en la que pueda acceder a los archivos como si fueran directorios:
mountavfs
Después de esto, si /path/to/archive.zip
es un archivo reconocido, entonces ~/.avfs/path/to/archive.zip#
es un directorio que parece contener el contenido del archivo.
find ~/.avfs"$PWD" \( -name '*.7z' -o -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
-exec sh -c '
find "$0#" -name "*vacation*.jpg"
' {} 'Test::Version' \;
Explicaciones:
- Montar el sistema de archivos AVFS.
- Busque archivos en
~/.avfs$PWD
, que es la vista AVFS del directorio actual.
- Para cada archivo, ejecute el fragmento de shell especificado (con
$0
= nombre de archivo y $1
= patrón para buscar).
$0#
es la vista de directorio del archivo $0
.
{\}
en lugar de {}
ser necesario en caso de que los find
sustitutos externos sean argumentos {}
internos -exec ;
(algunos lo hacen, otros no).
O en zsh ≥4.3:
mountavfs
ls -l ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)(e\''
reply=($REPLY\#/**/*vacation*.jpg(.N))
'\')
Explicaciones:
~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)
coincide con los archivos en la vista AVFS del directorio actual y sus subdirectorios.
PATTERN(e\''CODE'\')
aplica el CÓDIGO a cada coincidencia de PATRÓN. El nombre del archivo coincidente está en $REPLY
. Establecer la reply
matriz convierte la coincidencia en una lista de nombres.
$REPLY\#
es la vista de directorio del archivo.
$REPLY\#/**/*vacation*.jpg
coincide con *vacation*.jpg
archivos en el archivo.
- El
N
calificador global hace que el patrón se expanda a una lista vacía si no hay coincidencia.
Gilles 'SO- deja de ser malvado'
fuente
Mi solución habitual :
Ejemplo:
Los resultados son como:
Si solo desea el archivo zip con hits :
FILENAME aquí se usa dos veces, por lo que puede usar una variable.
Con find puedes usar PATH / TO / SEARCH
fuente
Otra solución que funciona es
zgrep
fuente
zgrep
es esa? Eso no funciona con el enviado con GNUgzip
(/bin/zgrep: -r: option not supported
,zgrep (gzip) 1.6
)En mi humilde opinión, la facilidad de uso también debería ser algo importante en bash:
y para alquitrán (este no ha sido probado ...)
fuente
unzip
implementación puede manejar archivos 7z o tar.gz?libarchive
'sbsdtar
puede manejar la mayoría de esos formatos de archivo, por lo que podría hacer:Que puede simplificar (y mejorar para que coincida entre mayúsculas y minúsculas) con GNU
find
con:Sin embargo, eso no imprime la ruta del archivo donde
*vacation*jpg
se encuentran esos archivos. Para imprimir ese nombre, puede reemplazar la última línea con:que da una salida como:
O con
zsh
:Tenga en cuenta que hay varios otros formatos de archivo que son justos
zip
otgz
archivos disfrazados como.jar
o.docx
archivos. Puede agregarlos a su patrónfind
/zsh
search,bsdtar
no le importa la extensión (como en, no depende de la extensión para determinar el tipo de archivo).Tenga en cuenta que lo
*vacation*.jpg
anterior coincide con la ruta completa del miembro de archivo, no solo con el nombre del archivo, por lo que coincidiría con,vacation.jpg
pero también convacation/2014/file.jpg
.Para hacer coincidir solo el nombre del archivo, un truco sería usar el modo de extracción , usar
-s
(sustitución) que usa expresiones regulares con unap
bandera para imprimir los nombres de los archivos coincidentes y luego asegurarse de que no se extraiga ningún archivo, como:Tenga en cuenta que generará la lista en stderr y se agregará
>>
a cada línea. En cualquier caso,bsdtar
como la mayoría de lastar
implementaciones, pueden alterar los nombres de los archivos que se muestran si contienen algunos caracteres como nueva línea o barra diagonal inversa (representados como\n
o\\
).fuente