Я хочу сделать сопоставление не жадных шаблонов (регулярных выражений) в awk
. Вот пример:
echo "@article{gjn, Author = {Grzegorz J. Nalepa}, " | awk '{ sub(/@.*,/,""); print }'
Можно ли написать регулярное выражение, которое выбирает более короткую строку?
@article{gjn,
вместо этой длинной строки?
@article{gjn, Author = {Grzegorz J. Nalepa},
Я хочу получить этот результат:
Author = {Grzegorz J. Nalepa},
У меня есть другой пример:
echo " , article {gjn, Author = {Grzegorz J. Nalepa}," | awk '{sub (/ , [^,] *, /, ""); Распечатать }' ↑ ↑ ^^^^^
Обратите внимание, что я изменил @
символы на символы запятой ( ,
) в первой позиции входной строки и регулярного выражения (а также изменился .*
на [^,]*
). Можно ли написать регулярное выражение, которое выбирает более короткую строку?
, Author = {Grzegorz J. Nalepa},
вместо более длинной строки?
,article{gjn, Author = {Grzegorz J. Nalepa},
Я хочу получить этот результат:
,article{gjn
awk
regular-expression
nowy1
источник
источник
Author
после запятой и пробела, а затем через пробел следует=
затем пробел следует{
вслед за чем не-}
следует}
, хотя это требует (помимо всего прочего) , что вы не можете вкладывать{}
внутрь= { ... }
части.Ответы:
Если вы хотите выбрать
@
и до первого,
после этого, вам нужно указать его как@[^,]*,
То есть
@
следует любому количество (*
) , не являющихся запятые ([^,]
) с последующей запятой (,
).Этот подход работает как эквивалент
@.*?,
, но не для таких вещей, как@.*?string
то, где то, что после, больше, чем один символ. Отрицание символа легко, но отрицание строк в регулярных выражениях намного сложнее .Другой подход состоит в том, чтобы предварительно обработать ввод, чтобы заменить или добавить
string
символ, который иначе не встречается в вводе:Если вы не можете гарантировать, что ввод не будет содержать заменяющего вас символа (см.
\1
Выше), один из подходов заключается в использовании экранирующего механизма:Это работает для фиксированных
string
s, но не для произвольных регулярных выражений, как для эквивалента@.*?foo.bar
.источник
Уже есть несколько хороших ответов, предлагающих обходные пути для
awk
неспособности выполнять несжадные сопоставления, поэтому я предоставляю некоторую информацию об альтернативном способе сделать это с помощью Perl-совместимых регулярных выражений (PCRE). Обратите внимание, что большинство простыхawk
сценариев «сопоставить и распечатать» можно легко повторно реализовать сperl
помощью параметра-n
командной строки, а более сложные сценарии можно преобразовать с помощью переводчика a2p Awk в Perl.В Perl есть не жадный оператор, который можно использовать в скриптах Perl и во всем, что использует PCRE. Например, также реализовано в
-P
опции GNU grep .PCRE не идентичен регулярным выражениям Perl, но он очень близок. Это популярный выбор библиотеки регулярных выражений для многих программ, потому что она очень быстрая, а расширения Perl для расширенных регулярных выражений очень полезны.
Со страницы руководства perlre (1) :
источник
Это старый пост, но следующая информация может быть полезна для других.
Есть способ, по общему признанию грубый, выполнить не жадное сопоставление RE в awk. Основная идея состоит в том, чтобы использовать функцию match (string, RE) и постепенно уменьшать размер строки до тех пор, пока не произойдет сбой, что-то вроде (не проверено):
источник
Для общих выражений это можно использовать как несжадное совпадение:
Я использую это, основываясь на ответе @ JimMellander.
smatch
ведет себя какmatch
, возвращаясь:источник
В awk нет способа сделать не жадное сопоставление. Вы можете получить желаемый результат, хотя. Предложение Sch будет работать для этой линии. Если вы не можете полагаться на запятую, но «Автор» - это всегда начало того, что вы хотите, вы можете сделать это:
Если число символов, предшествующих автору, всегда одинаково, вы можете сделать это:
Вам просто нужно знать, как выглядят ваши данные по всему набору.
источник
Всегда есть выход. Данная проблема может быть решена довольно легко при использовании запятых в качестве разделителя.
Когда количество полей меняется, обычно требуется что-то немного лучшее. В таком случае поиск стоп-слов часто окупается, так как вы можете вырезать что-либо из строки, используя их. В контексте примера вот что я имею в виду под стоп-словами.
источник
Я знаю, что это старый пост. Но вот что-то, использующее awk в качестве OP в соответствии с запросом:
A = @ article {gjn2010jucs, Author = {Grzegorz J. Nalepa},
echo $ A | awk 'sub (/ @ [^,] * /, "")'
Вывод:,
Author = {Grzegorz J. Nalepa},
источник