Tengo algunos archivos de registros en machineB
este directorio /opt/ptd/Logs/
como se muestra a continuación: Mis archivos de registros son bastante grandes.
david@machineB:/opt/ptd/Logs$ ls -lt
-rw-r--r-- 1 david david 49651720 Oct 11 16:23 ptd.log
-rw-r--r-- 1 david david 104857728 Oct 10 07:55 ptd.log.1
-rw-r--r-- 1 david david 104857726 Oct 10 07:50 ptd.log.2
Estoy intentando escribir un script de shell genérico que debería intentar analizar todo mi archivo de registro en machineB
busca de un patrón particular e imprimir la línea que tiene esos patrones. Ejecutaré mi siguiente script de shell desde machineA
el cual se configuran todas las claves ssh, lo que significa que necesito buscar de forma remota los archivos de registros en la máquina B desde la máquina A.
#!/bin/bash
wordsToInclude="hello,animal,atttribute,metadata"
wordsToExclude="timeout,runner"
# now grep on the various log file for above words and print out the lines accordingly
Es decir, tendré palabras separadas por comas en wordsToInclude
la variable. Si mis registros contienen hello
palabras, imprima esa línea y también imprima la línea que contiene animal
palabras. Lo mismo ocurre con attribute
y metadata
palabras.
Y también tendré palabras separadas por comas en wordsToExclude
la variable. Si alguna de las líneas contiene esas palabras, no las imprima.
Por ahora voy a utilizar el formato anterior para almacenar las palabras, pero cualquier formato mejor me parece bien. Puedo tener una lista larga de palabras en wordsToInclude
una wordsToExclude
variable, por eso voy a almacenarlas en esas variables.
Sé cómo hacer un grep en un pequeño conjunto de variables. Si necesito hacer grep desde la línea de comando directamente en la máquina B, lo haré así:
grep -E 'hello|animal|atttribute|metadata' ptd.log | grep -v 'timeout'
Pero no estoy seguro de cómo combino esto en mi script de shell para poder realizar un grep ssh remoto en la máquina B desde la máquina A.
Respuesta1
Si está abierto a otros formatos, considere:
inc="hello|animal|atttribute|metadata"
exc="timeout|runner"
ssh machineB "grep -E '$inc' path/ptd.log | grep -vE '$exc'"
Alternativa más rápida
Si sus archivos de registro son grandes y busca palabras fijas, en lugar de expresiones regulares sofisticadas, es posible que desee considerar este enfoque:
inc='hello
animal
atttribute
metadata'
exc='timeout
runner'
ssh office "grep -F '$inc' ptd.log | grep -vF '$exc'"
Al poner cada palabra en una línea separada, podemos usar -F
la función grep para cadenas fijas. Esto desactiva el procesamiento de expresiones regulares, lo que hace que el proceso sea más rápido.
Respuesta2
Puede que no parezca posible, pero puede utilizar la opción grep
de -f
para utilizar esa lista de palabras, aunque estén en una variable de entorno y no en un archivo adecuado. El truco está en engañarse grep
pensando que provienen de un archivo como este:
$ ssh machineB 'grep -f <(echo $wordsToInclude|tr , "\n") file1 file2 file3'
Esto ejecutará el grep ...
comando de forma remota a través ssh
de la máquina B. Tomará su variable $wordsToInclude
y cambiará las comas a caracteres de final de línea ( ,
-> \n
). Esta lista de palabras luego se ingresa grep
a través de su -f
interruptor.
Para ejecutar esto a través de la lista de exclusión, simplemente agréguelo como un segundo grupo después del inicial a través de una tubería.
$ ssh machineB 'grep -f <(echo $wordsToInclude|tr , "\n") \
file1 file2 file3 | grep -vf <(echo $wordsToExclude)'
Respuesta3
SSH se ejecuta con un comando como este:
ssh host command
O en tu caso:
ssh -t machineB "grep -E \"$wordsToInclude\" ptd.log | grep -v \"$wordsToExclude\""
Esto -t
evita un "error ioctl". También recomendaría usar las palabras fijas de grep para aumentar la velocidad, como se especifica enesta respuestapor @John1024. Simplemente coloque cada palabra en su propia línea, como:
wordsToInclude='hello
animal
atttribute
metadata'
wordsToExclude='timeout
runner'
Y agregue -F
a las opciones de grep.