Как grep получить несколько строк с определенным форматом, но если в одной из строк есть определенное слово, не включать строки в результат

avatar
Alice
8 августа 2021 в 22:31
50
1
1

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

Формат, который я ищу, всегда начинается с <topicref, а затем должен иметь href="../, но после него будет текст. Например: href="../example.md". После этого он может иметь scope="peer", некоторые другие строки и заканчиваться либо >, либо />.

На данный момент я придумал регулярное выражение, адрес которого находит нужные мне строки:

pcregrep -HnM '<topicref(.*) href="..\/(.*).dita(.*)[^>]*'

Однако у меня возникают проблемы с фильтрацией результатов, имеющих scope="peer". Я пытался сделать

pcregrep -HnM '<topicref(.*) href="..\/(.*).dita(.*)[^>]*' directory | pcregrep - Mv 'scope="peer" > file

Но результаты этого будут строго отображать все строки, в которых нет 'scope="peer"', из общего результата предыдущего pcregrep, поэтому будут случайные результаты, которые не должны быть включены, а также я не могу отследить, из каких файлов эти результаты.

Можно ли увидеть все упоминания <topicref href="../... > без scope="peer"?

Три примера строк с scope="peer":

<topicref href="../cat.md" scope="peer"
something />

<topicref href="../cat.md"
something scope="peer"
something />

<topicref href="../cat.md"
scope="peer"
something></topicref><map>
Источник
Mark Setchell
9 августа 2021 в 00:55
0

Я думаю, вам нужен "отрицательный обзор"... caspar.bgsu.edu/~courses/Stats/Labs/Handouts/grepadvanced.htm

Ответы (1)

avatar
Wiktor Stribiżew
9 августа 2021 в 21:22
0

Вы можете использовать

pcregrep -HnM '<topicref(?![^>]*\sscope="peer")(?:\s[^>]+)?\shref="\.\./([^"]*)\.dita[^>]*>' file

Подробности

  • <topicref - литеральная строка
  • (?![^>]*\sscope="peer") - не допускается использование пробела + scope="peer" после любого нуля или более символов, кроме > непосредственно справа от текущей позиции
  • (?:\s[^>]+)? - необязательный пробел, один или несколько символов, отличных от >
  • \shref="\.\./ - пробел, href="../ строка
  • ([^"]*) - Группа 1: ноль или более символов, кроме "
  • \.dita - строка .dita (замените на \.md, если вам нужно найти соответствие .md)
  • [^>]*> - ноль или более символов, кроме > и затем >.