У меня в 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.