Сравнивать строки, если они содержатся в bash

#bash

#bash

Вопрос:

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

Я пытаюсь сравнить их с if

 error="[*] Text Text @ level 4: 'Some text' [parent = 'Not found'] "
exception="'Not found'"
if [[ "${error}" == *"${exception}"* ]]; then                                   
    echo "Yes it contains!"
fi
  

В этом случае я бы ожидал, что скрипт вернет «Да, он содержит!», но это работает не так, как я ожидал. Но это правда, что мои журналы также содержат специальные символы, кто-нибудь знает, как мне с этим справиться и сравнить?


Для меня мой if тоже работает, но у меня может быть что-то не так во вложенном цикле. Я запускаю скрипт в следующем процессе.

  1. У меня есть файл с ошибками, вызываемыми mylogfile.txt :

     [*] Text Text @ level 4: 'Some text' [parent = 'Not found']
      
  2. Тогда у меня есть другой файл, в который я вставил исключения exception.txt :

     'Not found'
      
  3. Я делаю цикл над обоими файлами, чтобы посмотреть, найду ли я что-нибудь:

     while IFS='' read -r line || [ -n "$line" ]; do 
        exception="$line"                       
        while IFS='' read -r line || [ -n "$line" ]; do
            err="$line"                                                 
            if [[ "${err}" == *"${exception}"* ]]; then                                 
                echo "Yes it contains!"
            fi                  
        done < "mylogfile.txt"                  
    done < "exception.txt"
      

Комментарии:

1. У меня это работает. Можете ли вы поделиться фактической строкой, которая не работает? Возможно, запустите его через xxd , чтобы показать специальные символы.

Ответ №1:

Я не вижу ничего плохого в вашем скрипте, и он работает, когда я его запускаю.

Тем не менее, перебор файлов построчно в сценарии оболочки — это запах кода. Иногда это необходимо, но часто вы можете обманом заставить ту или иную команду выполнить тяжелую работу за вас. При поиске по файлам используйте grep. В этом случае вы действительно можете избавиться от обоих циклов с помощью одного grep!

 $ grep -f exception.txt mylogfile.txt
[*] Text Text @ level 4: 'Some text' [parent = 'Not found']
  

Чтобы использовать это в if инструкции, добавьте -q для подавления ее обычного вывода и просто проверьте код выхода:

 if grep -qf exception.txt mylogfile.txt; then
    echo "Yes, it's contained!"
fi
  

С справочной страницы grep(1):

FILE -f, —file=FILE

  • Получите шаблоны из файла, по одному на строку. Пустой файл содержит нулевые шаблоны и, следовательно, ничему не соответствует.

-q, —quiet, —silent

  • Тихо; не записывайте ничего в стандартный вывод. Немедленно завершите работу с нулевым статусом, если найдено какое-либо совпадение, даже если была обнаружена ошибка.

Ответ №2:

Используйте grep , если хотите точного совпадения

 if grep -q "$exception" <<< "$error"; then
    echo "Yes it contains!"
fi
  

Используйте -i переключатель, чтобы игнорировать регистр

Комментарии:

1. Нет необходимости использовать grep ; шаблон, который использует OP, должен работать.