Как выполнить grep на удаленной машине и вывести строку, содержащую эти слова?

Как выполнить grep на удаленной машине и вывести строку, содержащую эти слова?

У меня в machineBэтом каталоге есть несколько файлов журналов /opt/ptd/Logs/, как показано ниже. Мои файлы журналов довольно большие.

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

Я пытаюсь написать универсальный скрипт оболочки, который должен попытаться проанализировать все мои файлы журналов machineBна предмет определенного шаблона и вывести строку, содержащую эти шаблоны. Я запущу свой скрипт оболочки ниже, из machineAкоторого все ключи ssh настраивают все, что означает, что мне нужно удаленно выполнить grep для файлов журналов на machineB с machineA.

#!/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

То есть, у меня будут слова, разделенные запятой в wordsToIncludeпеременной - Если мои логи содержат helloслово, то вывести эту строку, также вывести строку, содержащую animalслово. Аналогично с attributeи metadataсловами.

А также я буду разделять слова запятыми в wordsToExcludeпеременной - если какая-либо из строк содержит эти слова, то не выводить эту строку.

Я сейчас использую указанный выше формат для хранения слов, но мне подойдет любой лучший формат. Я могу хранить длинный список слов в wordsToIncludeпеременной wordsToExclude, поэтому я буду хранить их в этих переменных.

Я знаю, как сделать grep на небольшом наборе переменных. Если мне нужно сделать grep из командной строки прямо на machineB, то я сделаю это так -

grep -E 'hello|animal|atttribute|metadata' ptd.log | grep -v 'timeout'

Но я не уверен, как мне объединить это в моем скрипте оболочки, чтобы я мог выполнить удаленный ssh ​​grep на machineB с machineA.

решение1

Если вы открыты для других форматов, рассмотрите:

inc="hello|animal|atttribute|metadata"
exc="timeout|runner" 
ssh machineB "grep -E '$inc' path/ptd.log | grep -vE '$exc'"

Более быстрая альтернатива

Если ваши файлы журналов большие и вы ищете фиксированные слова, а не сложные регулярные выражения, вы можете рассмотреть следующий подход:

inc='hello
animal
atttribute
metadata'

exc='timeout
runner'

ssh office "grep -F '$inc' ptd.log | grep -vF '$exc'"

Помещая каждое слово на отдельную строку, мы можем использовать -Fфункцию grep для фиксированных строк. Это отключает обработку регулярных выражений, ускоряя процесс.

решение2

Это может показаться невозможным, но вы можете использовать grepопцию , -fчтобы использовать этот список слов, даже если они находятся в переменной окружения, а не в надлежащем файле. Хитрость заключается в том, чтобы обмануть, grepзаставив думать, что они из файла, например:

$ ssh machineB 'grep -f <(echo $wordsToInclude|tr , "\n") file1 file2 file3'

Это запустит grep ...команду удаленно через sshмашину B. Она возьмет вашу переменную $wordsToIncludeи переключит запятые на символы конца строки ( ,-> \n). Затем этот список слов будет передан grepчерез ее -fпереключатель.

Чтобы пропустить это через список исключений, просто добавьте это как второй grep после первоначального через конвейер.

$ ssh machineB 'grep -f <(echo $wordsToInclude|tr , "\n") \
    file1 file2 file3 | grep -vf <(echo $wordsToExclude)'

решение3

SSH запускается с помощью такой команды:

ssh host command

Или в вашем случае:

ssh -t machineB "grep -E \"$wordsToInclude\" ptd.log | grep -v \"$wordsToExclude\""

Предотвращает -t"ошибку ioctl". Я бы также рекомендовал использовать фиксированные слова grep для увеличения скорости, как указано вэтот ответот @John1024. Просто поместите каждое слово на отдельную строку, например:

wordsToInclude='hello
animal
atttribute
metadata'

wordsToExclude='timeout
runner'

И добавьте -Fк параметрам grep.

Связанный контент