Используйте grep в массиве

#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.