Estoy usando un script para descargar regularmente mis mensajes de gmail que comprimen el .eml sin formato en archivos .gz. El script crea una carpeta para cada día y luego comprime cada mensaje en su propio archivo.
Me gustaría una forma de buscar en este archivo una "cadena".
Grep solo no parece hacerlo. También probé SearchMonkey.
zgrep
:zgrep - search possibly compressed files for a regular expression
Respuestas:
Si desea grep recursivamente en todos los archivos .eml.gz en el directorio actual, puede usar:
Tienes que escapar del primero
*
para que el shell no lo interprete.-print0
le dice a find que imprima un carácter nulo después de cada archivo que encuentre;xargs -0
lee de la entrada estándar y ejecuta el comando después de cada archivo;zgrep
funciona comogrep
, pero descomprime el archivo primero.fuente
zgrep
en realidad parece más rápido quegrep
ejecutarse en archivos sin comprimir. Debe ser porque los archivos comprimidos se pueden leer de la HD y descomprimir más rápido que leer un archivo sin comprimir de la HD.xargs
usa espacios en blanco (espacios en blanco) de forma predeterminada. Claro, los archivos casi nunca tienen líneas nuevas, pero los espacios no son desconocidos (incluso si la mayoría de los tipos UNIXy fruncen el ceño). Dicho esto, puede simplificar sin preocuparse por el espacio en blanco aún más fácilmente:find . -name '*.eml.gz' -exec zgrep "STRING" {} +
obtiene los mismos muchos argumentos por lanzamientoxargs
, la seguridad de-print0
/-0
, y todo sin la sobrecarga de un proceso adicional de lanzamiento y tubería, y de manera bastante concisa.-exec
con+
se especifica POSIX, por lo que debería estar en la mayoría de los sistemas semi-recientes similares a UNIX, que yo sepa.ABCLog04_18_18_2_21.gz
¿Hay alguna manera de buscar de forma recursiva los archivos que comienzan con ABC *. Intenté reemplazar\*.eml.gz
en su ejemplo anterior conABCLog*
y recibí un error sobre el formato de archivo .:find: paths must precede expression: ABCLog-2018-03-12-10-16-1.log.gz Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
Aquí hay mucha confusión porque no hay una sola
zgrep
. Tengo dos versiones en mi sistema,zgrep
desdegzip
yzgrep
desdezutils
. El primero es solo un script envoltorio que llamagzip -cdfq
. No es compatible con el-r, --recursive
interruptor. 1Este último es un
c++
programa y admite la-r, --recursive
opción.La ejecución
zgrep --version | head -n 1
revelará cuál de ellos (si corresponde) es el predeterminado:es el script de envoltura,
es el
cpp
ejecutableSi tienes este último, puedes ejecutar:
De todos modos, como se sugiere,
find
+zgrep
funcionará igualmente bien con cualquier versión dezgrep
:Si
zgrep
falta en su sistema (muy poco probable), puede probar con:pero hay una desventaja importante: no sabrá dónde están las coincidencias ya que no hay un nombre de archivo antepuesto a las líneas coincidentes.
1: porque sería problemático
fuente
zgrep
desde zutils no está disponible, puede instalarlo en Ubuntu consudo apt-get install zutils
.grep -n
,zgrep -n
imprimirá los números de línea. Está en el manual ...ag
es una variante degrep
, con algunas características adicionales agradables.Entonces:
Si no está instalado,
fuente
ag: truncated file: Success
como resultado. ¿Alguna otra bandera debo agregar?La recursión sola es fácil:
Sin embargo, para archivos comprimidos necesita algo como:
path/to/directory
debe ser el directorio principal que contiene los subdirectorios para cada día.zgrep
es la respuesta obvia pero, desafortunadamente, no es compatible con la-r
bandera. Deman zgrep
:fuente
Si su sistema tiene zgrep, simplemente puede
zgrep -irs your-pattern-goes-here the-folder-to-search-goes-here/
Si su sistema no tiene zgrep, puede usar el comando find para ejecutar zcat y grep en cada archivo de la siguiente manera:
find the-folder-to-search-goes-here/ -name '*.gz' \ -exec sh -c 'echo "Searching {}" ; zcat "{}" | grep your-pattern-goes-here ' \;
fuente
Searching ~/gmvault-db/db/2015-02/03/whatever.gz
zgrep
no tomará la-r
bandera por alguna razón. Esa es la mención enman zgrep
(también vea mi respuesta).xzgrep es una derivada de las utilidades de zgrep (less / bin / xzgrep)
Desde la página Man:
-l imprimo el nombre del archivo coincidente
-R para la recursión no funcionará, ya que está específicamente prohibido en el script, sin embargo, el simple bloqueo de shell debería llevarnos allí
desde una ruta relativa donde ./today/sample.eml.gz, coincida en todas las instancias que estén un nivel por debajo de nuestra posición relativa en el shell, que termina con ".eml.gz"
fuente