Grep по блоку текста\строк

Grep по блоку текста\строк

У меня есть текст, который содержит несколько строк. Поэтому мне нужно сделать GREP из нескольких строк. Например, у меня есть повторяющийся текст и мне нужно GREP получить строки, которые содержат эти повторяющиеся ключевые слова.

grep -o "test|test2" textfile

Мой текст:

123|never for your|test
123421|never for your|test2
123412|never for your|test3
12341|never for your|test4
12311|never for your|test2
123312312|never for your|test
123321312|never for your|test2

Мне следует иметь:

123|never for your|test
123421|never for your|test2
123312312|never for your|test
123321312|never for your|test2

Работает, но не так, как мне нужно. Поиск в тексте, все слова "test" и "test2". Но я хочу получить текстовые блоки, как какой-то шаблон, где только после "test" идет "test2". Есть идеи?

решение1

Краткий скрипт оболочки с использованием sed. Создает список номеров строк для второго случая и сравнивает с номерами строк для первого случая. Выводит совпадающие пары. Использует первый аргумент как имя файла. Можно легко расширить, чтобы использовать второй и третий аргументы как шаблоны для сопоставления. Можно сохранить как findnext.sh и запустить:

$ sh findnext.sh testfile

Должно быть быстро, так как требуется всего два прохода по файлу, и имеет преимущество в том, что является полностью портативным.

#!/bin/sh 
# Line numbers matching test1
mt2=$(sed -ne '/test1/=' < $1 | tr '\n' '/')

for l in $(sed -ne '/test/=' < $1); do
    nextline=$(expr $l + 1)
    [ "${mt2#*$nextline/}" != "$mt2" ] && sed -ne $l,${nextline}p <$1
done

решение2

Вы можете попробовать grep -E или egrep. Попробуйте вот так

#this will show lines that have test or test2
    grep -E "test|test2" file

Если вы хотите отобразить строку, которая содержит test и test2, например test|test2, сделайте это

# This will show lines that has test|test2
    grep "test\|test2" file

решение3

awkможет быть вашим инструментом для этого:

awk '/test$/, /test2$/' < block-text-lines.txt 

общая форма:

awk '/start-pattern/, /end-pattern/{command}'

Но поскольку блок команд по умолчанию настроен на печать, достаточно использовать только шаблоны начала и конца.

Проверьте man awkилиРуководство пользователя Gnu AwkдляспособПодробнее.

решение4

grep -A 1 "test$" in.txt | grep -B 1 "test2$"

В руководстве grep

-A NUMВывести NUM строк конечного контекста после совпадающих строк.

-B NUMВывести NUM строк начального контекста перед сопоставляемыми строками.

Команда grep -Pzo ".*test$\n.*test2$" in.txtтакже работает, но в руководстве указано: «Это экспериментальная команда, и grep -P может выдать предупреждение о нереализованных функциях».

Связанный контент