Я пытаюсь напечатать строки, используя символ повторения {n}, но это не работает. За. например, я хочу напечатать все строки длиной 4 символа
awk '/^.{4}$/' test_data
Приведенный выше код не печатает это. Как это исправить, чтобы я мог использовать символ повторения? Я знаю альтернативу, как awk '/^....$/' test_data
иawk 'length ==3 ' test_data
awk
regular-expression
Навсегда ученик
источник
источник
awk '/^.{4}+$/{print}' <<<$'foods\nbaarsz\nfooo'
чтобы соответствовать ровно 4 символа. Также, как вы упомянули сами,awk 'length($0) == 4' test_data
совместим практически со всемиawk
версиями.awk --re-interval '/^.{4}$/' test_data
илиawk --posix '/^.{4}$/' test_data
работать?Ответы:
Согласно Руководству пользователя GNU Awk: История возможностей , поддержка операторов диапазона регулярных выражений была добавлена в версии 3.0, но изначально требовался явный параметр командной строки.
Новые параметры командной строки:
В
gawk
4.0Поскольку вы используете
gawk
3.x, вам нужно будет использоватьили
или (спасибо @ StéphaneChazelas), если вы хотите портативное решение, используйте
(так как
--posix
или--re-interval
может вызвать ошибку в другихawk
реализациях).источник
POSIXLY_CORRECT=anything awk '/^.{4}/'
поскольку это создает переносимый код (--posix
или--re-interval
может вызвать ошибку в другихawk
реализациях).ERE ( расширенные регулярные выражения, используемые
awk
илиegrep
) изначально не имели{x,y}
. Впервые он был введен в BRE (как используетсяgrep
илиsed
), но с\{x,y\}
синтаксисом, который не нарушал обратной переносимости.Но когда он был добавлен в ERE с этим
{x,y}
синтаксисом, он сломал обратную переносимость, так какfoo{2}
RE раньше соответствовал чему-то другому.Поэтому некоторые реализации решили не делать этого. Вы найдете это
/bin/awk
,/bin/nawk
и/bin/egrep
в Solaris все еще не соблюдаете это (вы должны использовать/usr/xpg4/bin/awk
или/usr/xpg4/bin/grep -E
). То же самое дляawk
иnawk
на FreeBSD ( на основе поддерживается Брайан Керниган (далее в )).awk
k
awk
Для GNU
awk
, до относительно недавнего времени (версия 4.0), вы должны были вызватьPOSIXLY_CORRECT=anything awk '/^.{4}$/'
его, чтобы почтить его.mawk
все еще не соблюдает это .Обратите внимание, что этот оператор является только синтаксическим сахаром.
.{3,5}
например, всегда может быть написано....?.?
(хотя, конечно{3,5}
, это намного более разборчиво, и эквивалент(foo.{5,9}bar){123,456}
будет намного хуже).источник
Это работает, как и ожидалось с GNU
awk
(gawk):Но сбои,
mawk
которые ближе к POSIXawk
и, по умолчанию, в системах Ubuntu, AFAIK:Таким образом, простое решение будет использовать
gawk
вместоawk
.{n}
Обозначение не является частью синтаксиса POSIX BRE (базовое регулярное выражение). Вот почемуgrep
также не удается здесь:Однако это часть ERE (расширенные регулярные выражения):
Я не знаю, какой вкус регулярных выражений используется, Они используют старую версию ERE в соответствии с ответом Стефана . В любом случае, либо вы, очевидно, используете версиюmawk
POSIX или POSIXawk
, но я предполагаю, что это BREawk
, которая не реализует ERE, либо ваш ввод фактически не содержит строк с ровно 4 символами. Это может произойти, например, из-за пробелов, которые вы не видите, или из символов Unicode.источник
length($0)
более эффективные, чем регулярные выражения.mawk
на самом деле не ближе к POSIXawk
и не использует BRE. Он использует ERE, но без{x,y}
оператора.