Si j'ai une commande awk
pattern { ... }
et le motif utilise un groupe de capture, comment puis-je accéder à la chaîne ainsi capturée dans le bloc ?
Si j'ai une commande awk
pattern { ... }
et le motif utilise un groupe de capture, comment puis-je accéder à la chaîne ainsi capturée dans le bloc ?
Avec gawk, vous pouvez utiliser le match
pour capturer les groupes entre parenthèses.
gawk 'match($0, pattern, ary) {print ary[1]}'
exemple :
echo "abcdef" | gawk 'match($0, /b(.*)e/, a) {print a[1]}'
sorties cd
.
Notez l'utilisation spécifique de gawk qui implémente la fonctionnalité en question.
Pour une alternative portable, vous pouvez obtenir des résultats similaires avec match()
y substr
.
exemple :
echo "abcdef" | awk 'match($0, /b[^e]*/) {print substr($0, RSTART+1, RLENGTH-1)}'
sorties cd
.
C'était une promenade dans le passé...
J'ai remplacé awk par perl il y a longtemps.
Apparemment, le moteur d'expression régulière de AWK ne capture pas ses groupes.
vous pouvez envisager d'utiliser quelque chose comme :
perl -n -e'/test(\d+)/ && print $1'
l'option -n permet à perl de boucler sur chaque ligne comme le fait awk.
Apparemment, quelqu'un n'est pas d'accord. Cette page Web date de 2005 : tek-tips.com/faqs.cfm?fid=5674 Cela confirme que vous ne pouvez pas réutiliser les groupes appariés en awk.
C'est quelque chose dont j'ai besoin tout le temps, alors j'ai créé une fonction bash pour cela. Elle est basée sur la réponse de Glenn Jackman.
Ajoutez ceci à votre .bash_profile, etc.
function regex { gawk 'match($0,/'$1'/, ary) {print ary['${2:-'0'}']}'; }
Capture de la regex pour chaque ligne du fichier
$ cat filename | regex '.*'
Capture du 1er groupe de capture regex pour chaque ligne du fichier
$ cat filename | regex '(.*)' 1
@OlleHärstedt Non, ça ne pourrait pas. Cela ne couvre que votre cas d'utilisation lorsque vous n'avez pas de groupes de capture. Dans ce cas, les choses se gâtent avec les groupes de capture chaînés. grep -o
's.
Ed Morton : cela mérite une réponse de haut niveau je dirais. edit : uhm... cela imprime RewriteRule (.*) http://www.mysite.net/$
pour moi, ce qui est plus que le sous-groupe.
Vous pouvez également simuler la capture dans l'awk vanilla, sans extensions. Mais ce n'est pas intuitif :
étape 1 : utilisez gensub pour entourer les correspondances d'un caractère qui n'apparaît pas dans votre chaîne. étape 2. Utilisez split contre le caractère. étape 3. Chaque autre élément du tableau divisé est votre groupe de capture.
$ echo 'ab cb ad' | awk '{ split(gensub(/a./,SUBSEP"&"SUBSEP,"g",$0),cap,SUBSEP); print cap\[2\]"|" cap\[4\] ; }'
ab|ad
Je suis presque certain que gensub
est un gawk
fonction spécifique. Qu'obtenez-vous de votre awk si vous tapez awk --version
;- ?). Bonne chance à tous.
Je suis tout à fait certain que gensub est un gawk-ism, bien que BusyBox awk l'ait aussi. Cette réponse pourrait aussi être implémentée en utilisant gsub, cependant : echo 'ab cb ad' | awk '{gsub(/a./,SUBSEP"&"SUBSEP);split($0,cap,SUBSEP);print cap[2]"|"cap[4]}'
Gensub() est une extension de gawk, le manuel de gawk le dit clairement. D'autres variantes d'awk peuvent également l'implémenter, mais ce n'est toujours pas POSIX. Essayez gawk --posix '{gsub(...)}' et il se plaindra de ce qui suit
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
3 votes
stackoverflow.com/questions/1555173/
0 votes
Parfois (dans des cas simples), il est possible d'ajuster le séparateur de champs (
FS
) et choisir ce que l'on souhaite assortir d'une$field
. Le préformatage de l'entrée pourrait également être utile.1 votes
Il existe un meilleure réponse sur la question de la duplication.
3 votes
Samuel Edwin Ward : C'est aussi une belle réponse ! Mais il faut aussi
gawk
(puisqu'il utilisegensub
).0 votes
Il va sans dire que si vous effectuez une simple transformation, sed gère les groupes de capture de manière assez naturelle.