J'essaie d'imprimer les lignes en utilisant le symbole de répétition {n} mais cela ne fonctionne pas. Pour. par exemple, je veux imprimer toutes les lignes dont la longueur est de 4 caractères
awk '/^.{4}$/' test_data
Le code ci-dessus n'imprime pas cela. Comment le corriger pour que je puisse utiliser le symbole de répétition? Je connais l'alternative comme awk '/^....$/' test_data
etawk 'length ==3 ' test_data
awk
regular-expression
Forever Learner
la source
la source
awk '/^.{4}+$/{print}' <<<$'foods\nbaarsz\nfooo'
correspondre exactement à 4 caractères. Aussi, comme vous l'avez mentionné vous-même,awk 'length($0) == 4' test_data
est compatible avec presque toutes lesawk
versions.awk --re-interval '/^.{4}$/' test_data
ouawk --posix '/^.{4}$/' test_data
travailler?Réponses:
Selon le Guide de l'utilisateur de GNU Awk: historique des fonctionnalités , la prise en charge des opérateurs de plage d'expressions régulières a été ajoutée dans la version 3.0, mais l'option de ligne de commande explicite était initialement requise.
Nouvelles options de ligne de commande:
Dans
gawk
4.0,Puisque vous utilisez
gawk
3.x, vous devrez utiliserou
ou (merci @ StéphaneChazelas) si vous voulez une solution portable, utilisez
(car
--posix
ou--re-interval
provoquerait une erreur dans d'autresawk
implémentations).la source
POSIXLY_CORRECT=anything awk '/^.{4}/'
car cela rend le code portable (un--posix
ou--re-interval
provoquerait une erreur dans d'autresawk
implémentations).Les ERE ( expressions régulières étendues utilisées par
awk
ouegrep
) n'avaient pas initialement{x,y}
. Il a été introduit pour la première fois dans les BRE (tel qu'utilisé pargrep
oused
), mais avec une\{x,y\}
syntaxe qui n'a pas brisé la portabilité en arrière.Mais quand il a été ajouté aux ERE avec cette
{x,y}
syntaxe, il a rompu la portabilité en arrière car unfoo{2}
RE correspondait à quelque chose de différent auparavant.Certaines implémentations ont donc choisi de ne pas le faire. Vous constaterez que
/bin/awk
,/bin/nawk
et/bin/egrep
sur Solaris encore ne respecte pas (vous devez utiliser/usr/xpg4/bin/awk
ou/usr/xpg4/bin/grep -E
). Idem pourawk
etnawk
sur FreeBSD (basé sur la versionawk
maintenue par Brian Kernighan (l'k
inawk
)).Pour GNU
awk
, jusqu'à relativement récemment (version 4.0), vous deviez l'appeler avecPOSIXLY_CORRECT=anything awk '/^.{4}$/'
pour l'honorer.mawk
ne l'honore toujours pas .Notez que cet opérateur n'est que du sucre syntaxique.
.{3,5}
peut toujours être écrit....?.?
par exemple (bien que, bien sûr, il{3,5}
soit beaucoup plus lisible et que l'équivalent(foo.{5,9}bar){123,456}
soit bien pire).la source
Cela fonctionne comme prévu avec GNU
awk
(gawk):Mais échoue avec
mawk
ce qui est plus proche de POSIXawk
et, AFAIK, est la valeur par défaut sur les systèmes Ubuntu:Ainsi, une solution simple serait d'utiliser à la
gawk
place deawk
. La{n}
notation ne fait pas partie de la syntaxe POSIX BRE (expression régulière de base). C'est pourquoigrep
échoue également ici:Cependant, il fait partie des ERE (expressions régulières étendues):
Je ne sais pas quelle saveur regex est utilisée par. Ils utilisent une ancienne version d'ERE selon la réponse de Stéphane . Dans tous les cas, soit vous utilisez apparemment une versionmawk
ou POSIXawk
, mais je suppose que c'est BREawk
qui n'implémente pas ERE ou votre entrée n'a en fait aucune ligne avec exactement 4 caractères. Cela peut se produire en raison d'espaces vides que vous ne voyez pas ou de glyphes unicode, par exemple.la source
length($0)
ce qui est plus efficace que les expressions régulières.mawk
n'est pas vraiment plus proche de POSIXawk
et n'utilise pas de BRE. Il utilise des ERE mais sans l'{x,y}
opérateur.