
У меня есть текст, который содержит несколько строк. Поэтому мне нужно сделать 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 может выдать предупреждение о нереализованных функциях».