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 ne s'imprime pas. Comment le corriger pour que je puisse utiliser le symbole de répétition? Je connais l'alternative comme awk '/^....$/' test_data
et awk 'length ==3 ' test_data
Selon le Guide de l'user de GNU Awk: Historique des fonctionnalités , la prise en charge des opérateurs de plage d'expression régulière a été ajoutée dans la version 3.0, mais a initialement nécessité l'option de command line explicite
Nouvelles options de command line:
- Nouvelles options de command line:
- L'option –lint-old pour avertir des constructions qui ne sont pas disponibles dans la version Unix d'origine de la version 7 d'awk (voir V7 / SVR3.1).
- L'option -m de BWK awk. (Brian était encore aux Laboratoires Bell à l'époque.) Ce fut plus tard retiré de son awk et de gawk.
- L'option –re-interval pour fournir des expressions d'intervalle dans les expressions rationnelles (voir Opérateurs Regexp).
- L'option –traditional a été ajoutée en tant que meilleur nom pour –compat (voir Options).
Dans gawk
4.0,
Les expressions d'intervalle sont devenues partie intégrante des expressions régulières par défaut
Puisque vous utilisez gawk
3.x, vous devrez utiliser
awk --re-interval '/^.{4}$/'
ou
awk --posix '/^.{4}$/'
ou (merci @ StéphaneChazelas) si vous voulez une solution portable, utilisez
POSIXLY_CORRECT=anything awk '/^.{4}$/'
(puisque --posix
ou --re-interval
entraînerait une erreur dans d'autres implémentations awk
).
Les ERE ( expressions régulières étendues telles qu'utilisées par awk
ou egrep
) n'avaient initialement pas {x,y}
. Il a été introduit dans BREs (comme grep
ou sed
), mais avec la syntaxe \{x,y\}
qui n'a pas brisé la portabilité.
Mais quand il a été ajouté aux ERE avec cette syntaxe {x,y}
, il a brisé la portabilité en arrière comme un foo{2}
RE correspondait quelque chose de différent avant.
Certaines implémentations ont donc choisi de ne pas le faire. Vous findez que les /bin/nawk
/bin/awk
, /bin/nawk
et /bin/egrep
sur Solaris ne l'honorent toujours pas (vous devez utiliser /usr/xpg4/bin/awk
ou /usr/xpg4/bin/grep -E
). Idem pour awk
et nawk
sur FreeBSD (basé sur l' awk
maintenu par Brian Kernighan (le k
in awk
)).
Pour GNU awk
, jusqu'à relativement récemment (version 4.0), vous deviez l'appeler avec POSIXLY_CORRECT=anything awk '/^.{4}$/'
pour l'honorer. mawk
ne l' mawk
toujours pas .
Notez que cet opérateur n'est que du sucre syntaxique. .{3,5}
peut toujours être écrit ....?.?
par exemple (bien que {3,5}
soit beaucoup plus lisible, et l'équivalent de (foo.{5,9}bar){123,456}
serait bien pire).
Cela fonctionne comme prévu avec GNU awk
(gawk):
$ printf 'abcd\nabc\nabcde\n' | gawk '/^.{4}$/' abcd
Mais échoue avec mawk
qui est plus proche de POSIX awk
et, AFAIK, est le défaut sur les systèmes Ubuntu:
$ printf 'abcd\nabc\nabcde\n' | mawk '/^.{4}$/' $ ## prints nothing
Donc, une solution simple serait d'utiliser gawk
au lieu de awk
. La notation {n}
ne fait pas partie de la syntaxe POSIX BRE (expression régulière de base). C'est pourquoi grep
échoue également ici:
$ printf 'abcd\nabc\nabcde\n' | grep '^.{4}$' $
Cependant, il fait partie de ERE (expressions régulières étendues):
$ printf 'abcd\nabc\nabcde\n' | grep -E '^.{4}$' abcd
Je ne sais pas quelle 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 version de mawk
ou POSIX awk
, mais je suppose que c'est BRE awk
qui awk
pas ERE, soit votre input n'a pas de lignes avec exactement 4 caractères. Cela peut arriver en raison d'espaces blancs que vous ne voyez pas ou de glyphes unicode, par exemple.