#bash #shell
Вопрос:
Ниже приведен скрипт для поиска определенного массива различных слов «боты,шпионские программы,вирусы» в файле, если файл существует.
#!/bin/bash #strings to find in file NAME[0]="bots" NAME[1]="spyware" NAME[2]="virus" #location of file LOGS=/home/testing.txt #define function to grep any of the above mentioned array strings in file func(){ if `grep "${NAME[*]}" $LOGS`; then echo "CRITICAL: ${NAME[*]}" else echo "errors not found" exit fi } #file exist or not exist if [ -f $LOGS ]; then echo " File Found" #call functions func modified else echo "File Not Found" exit
Но grep "${NAME[*]}" $LOGS
это не работает. Это показывает ниже ошибку:
grep: virus: No such file or directory grep: bots: No such file or directory
Комментарии:
1. научитесь использовать
set -x
для включения трассировки отладки скрипта оболочки (set x
для отключения). И вы обнаружите, что вам нужно преобразовать свой arr в цель поиска, которая выглядит такgrep 'a|b|c' file
. И отличный 2-й вопрос, но нам нужно только увидетьfunc()
код, поэтому научитесь ориентировать свой Qs на нерабочий код. Удачи.
Ответ №1:
Вот решение для проблемной части.
Перейдите в if-body, когда grep найдет хотя бы одну запись массива KEYWORDS
в файле FILE
.
Следующий код работает для записей массива со специальными символами, такими как пробел или
*
.
KEYWORDS[0]="virus" KEYWORDS[1]="two words" KEYWORDS[2]="special chars . *?|()[]^amp;" if grep -qF "${KEYWORDS[@]/#/-e}" -- "$FILE"; then # found a keyword fi
Что здесь происходит?
grep -q
Ничего не выводите. Выходите на первом матче. Нам не нужно сканировать весь файл, если мы уже нашли ключевое слово.grep -F
Поиск по фиксированным строкам. Символы, такие как*
,|
, или"{KEYWORDS[@]}"
Каждая запись массива расширяется до одной строки в кавычках. Здесь"virus" "two words" "special chars . *?|()[]^amp;"
"${KEYWORDS[@]/#/-e}"
Добавляйте-e
к каждой записи массива. Grep может выполнять поиск по нескольким шаблонам, используя эту опцию.grep -e"FirstPattern" -e"SecondPattern" ...
grep Pattern -- "$FILE"
Это--
подсказка, которую"$FILE"
следует интерпретировать как имя файла. Можно назвать файл-eFunny
, который остановит наш скрипт, потому что grep подумает, что имя файла не указано, и будет ждать ввода от stdin. Здесь в этом нет особой необходимости, но это хорошая привычка. Так называемый двойной тире доступен для большинства команд, а не только для grep.