Tenho poucos arquivos de log neste machineB
diretório, /opt/ptd/Logs/
conforme mostrado abaixo - Meus arquivos de log são muito 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
Estou tentando escrever um script de shell genérico que deve tentar analisar todo o meu arquivo de log em machineB
busca de um padrão específico e imprimir a linha que contém esses padrões. Estarei executando meu script de shell abaixo, a partir do machineA
qual todas as chaves ssh configuram tudo, o que significa que preciso acessar remotamente os arquivos de log na máquina B da 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
Ou seja, terei palavras separadas por vírgula na wordsToInclude
variável - Se meus logs contiverem hello
palavra, imprima essa linha e imprima também a linha que contém animal
palavra. Da mesma forma com attribute
e metadata
palavras.
E também terei palavras separadas por vírgula na wordsToExclude
variável - se alguma das linhas contiver essas palavras, não imprima essas linhas.
Por enquanto, vou usar o formato acima para armazenar as palavras, mas qualquer formato melhor é adequado para mim. Posso ter uma longa lista de palavras wordsToInclude
e wordsToExclude
variáveis, por isso vou armazená-las nessas variáveis.
Eu sei como fazer um grep em um pequeno conjunto de variáveis. Se eu precisar executar o grep na linha de comando diretamente na máquina B, farei assim -
grep -E 'hello|animal|atttribute|metadata' ptd.log | grep -v 'timeout'
Mas não tenho certeza de como combinar isso em meu script de shell para poder fazer um ssh grep remoto na máquina B da máquina A.
Responder1
Se você estiver aberto a outros formatos, considere:
inc="hello|animal|atttribute|metadata"
exc="timeout|runner"
ssh machineB "grep -E '$inc' path/ptd.log | grep -vE '$exc'"
Alternativa mais rápida
Se seus arquivos de log forem grandes e você estiver procurando por palavras fixas, em vez de expressões regulares sofisticadas, você pode considerar esta abordagem:
inc='hello
animal
atttribute
metadata'
exc='timeout
runner'
ssh office "grep -F '$inc' ptd.log | grep -vF '$exc'"
Colocando cada palavra em uma linha separada, podemos usar -F
o recurso do grep para strings fixas. Isso desativa o processamento de regex, tornando o processo mais rápido.
Responder2
Pode não parecer possível, mas você pode usar grep
a opção ' -f
para usar essa lista de palavras, mesmo que elas estejam em uma variável de ambiente e não em um arquivo adequado. O truque é pensar grep
que eles são de um arquivo assim:
$ ssh machineB 'grep -f <(echo $wordsToInclude|tr , "\n") file1 file2 file3'
Isso executará o grep ...
comando remotamente por meio ssh
da máquinaB. Ele pegará sua variável $wordsToInclude
e mudará as vírgulas para caracteres de final de linha, ( ,
-> \n
). Essa lista de palavras é então alimentada grep
por meio de seu -f
switch.
Para executar isso através da lista de exclusão, basta adicioná-lo como um segundo grep após o inicial por meio de um pipe.
$ ssh machineB 'grep -f <(echo $wordsToInclude|tr , "\n") \
file1 file2 file3 | grep -vf <(echo $wordsToExclude)'
Responder3
O SSH é executado com um comando como este:
ssh host command
Ou no seu caso:
ssh -t machineB "grep -E \"$wordsToInclude\" ptd.log | grep -v \"$wordsToExclude\""
Isso -t
evita um "erro ioctl". Eu também recomendo usar as palavras fixas do grep para aumentar a velocidade, conforme especificado poresta respostapor @John1024. Basta colocar cada palavra em sua própria linha, como:
wordsToInclude='hello
animal
atttribute
metadata'
wordsToExclude='timeout
runner'
E adicione -F
às opções do grep.