Изменить разделитель команды grep - PullRequest
1 голос
/ 07 февраля 2012

Я использую grep для обнаружения <a href="xxxx"> something here </a>
Это не работает, когда ссылка разбита на две строки на входе. Я хочу, чтобы grep проверял, пока он не обнаружит </a>, но сейчас он только принимает входные данные в grep, пока не обнаружит новую строку.

Так что, если ввод похож на <a href="xxxx"> something here </a>, он работает, но если ввод похож на

<a href="xxxx">

something here /a>    

, тогда это не так. Любые решения?

Ответы [ 6 ]

3 голосов
/ 07 февраля 2012

Я бы использовал awk, а не grep. Это должно работать:

awk '/a href="xxxx">/,/\/a>/' filename

1 голос
/ 08 февраля 2012

Я бы предложил свернуть ввод, чтобы открывающие и закрывающие теги находились на одной и той же строке, а затем сравнивать линию с шаблоном. Идиоматический подход с использованием sed (1):

sed '/<[Aa][^A-Za-z]/{ :A
     /<\/[Aa]>/ bD
     N
     bA
     :D
     /\n/ s// /g
}
# now try your pattern
/<[Aa][^A-Za-z] href="xxx"[^>]*>[^<]*something here[^<]*<\/[Aa]>/ !d'
1 голос
/ 07 февраля 2012

Я думаю, что у вас было бы гораздо меньше проблем с использованием некоторого инструмента xslt, но вы можете сделать это с помощью sed, awk или расширенной версии grep pcregrep , которая поддерживает многострочный шаблон (-M).

0 голосов
/ 13 марта 2018

Рассмотрим egrep -3 '(<a|</a>)'

"- 3" печатает до 3 окружающих строк вокруг каждого совпадения с регулярным выражением (3 строки до и 3 строки после матча).Вы также можете использовать -1 или -2, если это работает лучше.

0 голосов
/ 13 марта 2018
perl -e '$_=join("", <>); m#<a.*?>.*?<.*?/a>#s; print "$&\n";'

Итак, хитрость в том, что весь ввод читается в $ _. Затем запускается стандартное /.../ регулярное выражение. Я использовал альтернативный синтаксис m # ... #, чтобы мне не пришлось использовать обратную косую черту "/", которые используются в xml. Наконец, постфикс «s» заставляет многострочные совпадения работать с помощью «.» также соответствует символу новой строки (обратите внимание также на опцию «m», которая меняет значения ^ и $). «$ &» - соответствующая строка. Это результат, который вы ищете. Если вам нужен только внутренний текст, вы можете заключить его в круглые скобки и вывести $ 1.

Я предполагаю, что вы подразумевали </a>, а не /a> как закрывающий разделитель xml.

Обратите внимание, что .*? - это не жадная версия .*, поэтому для <a>1</a><a>2</a> она соответствует только <a>1</a>.

Обратите внимание, что вложенные узлы могут вызывать проблемы, например <a><a></a></a>. Это то же самое, что и при попытке сопоставить вложенные скобки "(", ")" или "{", "}". Это более интересная проблема. Регулярные выражения обычно не сохраняют состояния, поэтому сами по себе не поддерживают сохранение неограниченной глубины вложенности скобок. При программировании синтаксических анализаторов вы обычно используете регулярные выражения для низкоуровневого сопоставления строк и что-то еще для более высокого уровня парсинга токенов, например, bison. Есть грамматики бизонов для многих языков и, вероятно, для xml. xslt может быть даже лучше, но я не знаком с этим. Но для очень простого случая использования вы можете также обрабатывать вложенные блоки, например, в perl:

Вложенный код обработки скобок: (его можно легко адаптировать для обработки вложенных блоков XML)

$_ = "a{b{c}e}f";

my($level)=(1);
s/.*?({|})/$1/; # throw away everything before first match
while(/{|}/g) {
   if($& eq "{") {
      ++$level;
   } elsif($& eq "}") {
      --$level;
      if($level == 1) {
         print "Result: ".$`.$&."\n";
         $_=$'; # reset searchspace to after the match
         last;
      }
   }
}

Result: {b{c}e}

0 голосов
/ 23 февраля 2012

Вероятно, это повторный вопрос: Grep строки поиска с переносами строк

Вы можете попробовать это с помощью команды tr '\n' ' ', как было объяснено в одном из ответов, если все, что вам нужно, это найти файлы, а не номера строк.

...