Проблема в том, что grep
будет выполняться в каждой строке, а не во всем файле. Пока файл достаточно мал, чтобы поместиться в память (что должно иметь место в подавляющем большинстве ситуаций в наши дни), вы можете использовать команду grep -z
флаг, чтобы проглотить весь файл:
-z, --null-данные
Рассматривайте входные и выходные данные как последовательности
строк, каждая из которых заканчивается нулевым байтом (код ASCII NUL
символ) вместо новой строки. Подобно опции -Z или --null, эту опцию можно использовать с командами
например, sort -z для обработки произвольных имен файлов.
Следующая проблема заключается в том, что если вы пройдете grep
что-то с новыми строками, он будет рассматривать это как список шаблонов для grep:
$ строка = "1
> 2"
$ последовательность 10 | grep "$ строка"
1
2
10
"
Это означает, что я боюсь, что вам придется выразить шаблон как правильное регулярное выражение:
\n\nтест1\n\nтест2\n\n
Однако это также означает, что вам нужно -П
флаг, чтобы включить Perl-совместимые регулярные выражения, чтобы \n
буду работать.
Я создал эти два файла для демонстрации:
$ cat файл1
Это тест:
тест1
тест2
и еще один
$ cat файл2
Это тест:
тест1
тест2
и еще один
Используя эти два файла и приведенную выше информацию, вы можете сделать:
$ grep -Pz '\n\ntest1\n\ntest2\n\n' файл1
$
$ grep -Pz '\n\ntest1\n\ntest2\n\n' файл2
Это тест:
тест1
тест2
и еще один
Совокупность всего этого дает нам:
строка = '\n\ntest1\n\ntest2\n\n'
если ! grep -Pzq "$string" test.txt; тогда
printf "$string" >> test.txt
фи
Или, как предложил @steeldriver в комментарии, вы можете использовать переменную и преобразовать новые строки в \n
на лету:
$ строка = "
тест1
тест2
"
$ если ! grep -Pzq "${string//$'\n'/\n}" test.txt; тогда
printf "$string" >> test.txt
фи
Если ваша строка содержит специальные символы, которые имеют значения в регулярных выражениях, как вы теперь показываете в своем обновленном вопросе, то это совершенно другая ситуация. Для примера, который вы показываете, вам понадобится что-то значительно более сложное. Как это:
searchString='\n\nif \[ -f ~/.script \]; затем\s*\n\s*\.\s+~/\.script\s*\nfi\n\n'
строка печати = '
если [-f ~/.script]; тогда
. ~/.скрипт
фи
'
если ! grep -Pzq "$searchString" test.txt; тогда
printf "%s" "$printString" >> test.txt
фи