Sortie de GNU Awk 4.1.0

Posté par  . Édité par Benoît Sibaud, tuiu pol, claudex et Nils Ratusznik. Modéré par Nils Ratusznik. Licence CC By‑SA.
Étiquettes : aucune
38
13
mai
2013
Communauté

Awk est l'interpréteur d'un langage spécifique destiné à « gérer les tâches simples de reformatage de données avec seulement quelques lignes de code », autrement dit manipuler du texte. L'applicatif gawk (abréviation de GNU Awk) est la version de cet interpréteur portée par le projet GNU. La version 4.1.0 de gawk est sortie le 10 mai, apportant son lot d'évolutions.

  1. Les trois exécutables gawk, pgawk, and dgawk, ont été fusionnés en un seul nommé gawk. Ce regroupement a permis de réduire considérablement l'empreinte de gawk et de simplifier la documentation. L'exécutable gawk évolue donc ainsi :
    • l'option -R a été supprimée ;
    • l'option -D (suivie optionnellement du nom d'un fichier de commandes à lancer préalablement) est le nouveau moyen de lancer le débogueur ;
    • l'option -o fournit le pretty-print ;
    • l'option -p permet le profilage de code.
  2. Gawk permet maintenant le calcul arithmétique multiprécision en virgule flottante avec arrondi correct avec la bibliothèque GNU MPFR. La double précision est toujours utilisée par défaut, mais on peut changer cela en définissant le paramètre PREC ou en utilisant les options -M / --bignum.
  3. La nouvelle option -i (option venant de xgawk) permet de charger un script awk. La différence avec l'option -f est que le premier argument qui n'est pas une option reste traitée comme un script
  4. La nouvelle option -l (venant de xgawk) permet de charger des bibliothèques dynamiques.
  5. L'interface de chargement des extensions dynamiques a été totalement revue. Il faut maintenant utiliser une API définie pour les extensions en C. Une extension en C agit comme une fonction écrite en awk, sauf qu'elle ne pourra pas faire tout ce que le code awk permet. Cependant, cela permet d'interfacer tout fonctionnalité disponible en C. Ceci est un développement majeur, se référer à la documentation qui a un sympathique chapitre définissant tout cela. L'ancien mécanisme d'extension est toujours pris en charge mais devrait définitivement disparaître de la prochaine version majeure de gawk.
  6. La nouvelle extension ''inplace'' permet d'émuler la fonctionnalité sed -i.
  7. Les fonctions and(), or() et xor() peuvent prendre maintenant plus de deux arguments.
  8. Nouveaux tableaux : SYMTAB, FUNCTAB, et PROCINFO["identifieur"] ; SYMTAB offre un accès indirect à toute variable ou tableau, il est donc possible de « parcourir » la table des symboles, si cela s'avérait nécessaire.
  9. La gestion de la compilation croisée de gawk a été améliorée.
  10. Mise à jour de l'infrastructure : bison 2.7.1, gettext 0.18.2.1, automake 1.13.1 et libtool 2.4.2 pour les extensions.

Aller plus loin

  • # Roh mais !!!

    Posté par  (site web personnel) . Évalué à 2.

    « gérer les tâches simples données reformatage avec seulement quelques lignes de code »

    hein ? quoi ? do you habla ਪੰਜਾਬੀ ?

    • [^] # Re: Roh mais !!!

      Posté par  (site web personnel) . Évalué à 1.

      Corrigé, merci.

    • [^] # Re: Roh mais !!!

      Posté par  (site web personnel) . Évalué à 2.

      J'en profite pour demander quelques corrections sur cette dépêche :

      • les apostrophes doivent être changées de "" vers «  »
      • « L'ancien mécanisme d'extension est toujours supporté mais… » ---> « L'ancien mécanisme d'extension est toujours pris en charge, mais…
      • cross-compilation --> compilation croisée
      • débugger --> débogueur
      • [^] # Re: Roh mais !!!

        Posté par  (site web personnel) . Évalué à 2.

        Corrigé, merci (guillemets pas apostrophes).

      • [^] # Re: Roh mais !!!

        Posté par  . Évalué à 2. Dernière modification le 13 mai 2013 à 14:51.

        Tant qu'on y est, j'ai envie d'écrire que « applicatif » est un néologisme bien moche et assez peu français. Utilitaire ou interprète serait plus adapté, je pense.

        EDIT : too late.

  • # great

    Posté par  . Évalué à 3.

    j'adore cet outil, à la fois hyper simple et très puissant.
    l'évolution sur les extensions en C me paraît intéressante ; j'ajoute ça à ma todo liste de choses à tester.

  • # inplace

    Posté par  . Évalué à 4.

    1. La nouvelle extension ''inplace'' permet d'émuler la fonctionnalité "sed -i".

    Ça c'est vraiment ce qui me manquait le plus !!!! :)

    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: inplace

      Posté par  . Évalué à 5.

      D'où l'intérêt d'utiliser perl

      • [^] # Re: inplace

        Posté par  . Évalué à 7.

        perl est bien, mais gawk est un peu plus concis et des fois plus efficace (je ne parle pas de performances). De plus awk c'est 25% plus court que perl :p

        Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

        • [^] # Perl

          Posté par  . Évalué à 6.

          perl est bien, mais gawk est un peu plus concis et des fois plus efficace (je ne parle pas de performances).

          Je demande à voir un exemple.

          perl -n permet d’émuler le comportement d’AWK (c’est-à-dire exécuter le code pour chaque ligne ; bon, ça fait quatre caractères en plus pour l’appel, le reste est de taille équivalente).
          -a permet l’auto-découpage des lignes en champs. -l supprime les retours chariots des fins de ligne (je ne sais pas s’il y a un équivalent AWK, mais parfois, c’est pratique).

          perl -p (à la place de -n) permet en plus d’imprimer les lignes après traitement (plus comme sed, mais celui-ci est beaucoup plus limité), alors qu’avec AWK, il faut le faire explicitement (sur ce coup-là, Perl est plus concis).

          Pour le reste, on dispose d’un langage bien plus puissant et avec un champ d’application bien plus vaste qu’AWK, sed et autres (et le même à chaque fois).

          En plus la syntaxe d’AWK n’est pas plus simple que celle de Perl (je fais encore un peu d’AWK, rarement, quand j’ai un petit script pour lequel je souhaite éviter la dépendance à Perl, et il y a quelques cas où la syntaxe d’AWK est même moins évidente).

          Alors bon, je remercie les développeurs qui maintiennent gawk, parce qu’AWK est malgré tout un bon outil sur lequel je suis bien content de pouvoir compter, même sur les systèmes hostiles (c’est-à-dire sans Perl installé — bon, les trucs sans Perl ni AWK, je ne considère pas ça comme des systèmes), mais franchement, j’utilise et je conseille Perl à la place de ces petits outils : autant investir son temps sur un langage unique avec des possibilités plus vastes. Si je ne m’étais pas mis à AWK avant Perl, je ne le ferais pas maintenant.

          « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

          • [^] # Re: Perl

            Posté par  . Évalué à 2.

            J'aime beaucoup perl, mais je ne le sort qu'en dernier recours pour des unilignes, parce qu'il est moins bien taillé pour. C'est des cas où je me fou de la puissance du langage je veux juste un truc qui répond à mon besoin.

            Par exemple si je veux sommet 2 colonnes d'un fichier

            J'ai la version perl post 5.10 :

            perl -lane 'print $F[0]+$F[1]' fichier
            
            

            La version perl post 5.10 :

            perl -anE 'say $F[0]+$F[1]' fichier
            
            

            Et awk :

            awk '{print $1+$2}' fichier
            
            

            Il y a des cas où il est bien meilleur, mais dans la majorité de mes cas d'utilisation, ce n'est pas le cas.

            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

            • [^] # Re: Perl

              Posté par  . Évalué à 4.

              http://www.gnu.org/software/gawk/manual/gawk.html#Extension-Sample-Inplace
              là je me dis qu'un perl -i.bak roxe des mamans ours

              • [^] # Re: Perl

                Posté par  . Évalué à 4.

                Justement c'est l'une des grosses critique que j'avais envers awk, mais maintenant que gawk 4.1 est sortie tu peux faire : awk -i.back¹ (c'est l'objet de mon commentaire tout en haut du fil).

                ¹ : oui ce n'est pas portable, mais ça sera au moins utilisable sur tous les linux d'ici la sortie de Debian Jessie.

                Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                • [^] # Re: Perl

                  Posté par  . Évalué à 4.

                  euh ce que j'ai vu dans la doc c'est plutôt un truc du style :
                  gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") } > { print }' file1 file2 file3
                  -i pour include ?

                  • [^] # Re: Perl

                    Posté par  . Évalué à 4.

                    J'avais présumé que la doc n'est pas à jour, mais en regardant la dernière version du logiciel en fait si. C'est dommage.

                    Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                    • [^] # Re: Perl

                      Posté par  . Évalué à 4.

                      Du coup, pour faire l’équivalent d’un usage typique de sed :

                      sed -i.bak 's/foo/bar/g' fichiers
                      
                      

                      avec Perl, ça donne ça :

                       perl -i.bak -pe 's/foo/bar/g' fichiers
                      
                      

                      alors qu’avec Gawk (et à condition d’avoir une version récente), ça donne ça :

                      gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar"); print }' fichiers
                      
                      

                      Là, question efficacité de codage, ce n’est clairement pas à l’avantage de gawk.

                      « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

                      • [^] # Re: Perl

                        Posté par  . Évalué à 3.

                        On est d'accord. J'utilise awk quand j'ai besoin de découper mes lignes :

                        env | awk -F= '$1=="LANG"{print $2}'
                        echo 'Hello world !' | awk '{$2="Arthur Accroc"; print}'
                        
                        

                        Bien sûr que l'on peut les faire avec des expressions régulières (en sed par exemple) :

                        env | sed -n 's/^LANG=//p'
                        echo 'Hello world !' | sed 's/world/Arthur Accroc/'
                        
                        

                        Ou en perl :

                        perl -E 'say $ENV{LANG}' # ça c'est un cas particulier, mais c'est bien de ne pas oublier que ça existe (et qui d'ailleurs m'a fait penser qu'en awk on peut faire awk 'BEGIN{print ENVIRON["LANG"]}'
                        echo 'Hello world !' | perl -pe 's/world/Arthur Accroc/'
                        
                        

                        Je crois que mes exemples sont mal choisis, un peu trop simple (les expressions régulières sont trivial et les délimiteurs simples).

                        Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                        • [^] # Re: Perl

                          Posté par  . Évalué à 4.

                          Je crois que mes exemples sont mal choisis, un peu trop simple (les expressions régulières sont trivial et les délimiteurs simples).

                          Oui, parce que ramener un découpage à une expression régulière, c’est toujours possible (même si d’autant plus lourd que le cas était simple), mais l’inverse…

                          Exemple, une petite uniligne pour s’assurer que les balises img de fichiers HTML sont bien de la forme <img src="toto.png /> selon les standards actuels et pas <img src="toto.png"> sans / :

                          perl -i.bak -pe 's{(<img\s.*?)\s*/?>}{$1 />}ig' *.html
                          
                          

                          (Note à ceux qui seraient tentés de l’utiliser : elle doit fonctionner sur de l’HTML correct, mais elle n’est pas foolproof : si une balise img n’a pas son chevron fermant, elle ira modifier le suivant…)

                          « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

                          • [^] # Re: Perl

                            Posté par  . Évalué à 3.

                            (Note à ceux qui seraient tentés de l’utiliser : elle doit fonctionner sur de l’HTML correct, mais elle n’est pas foolproof : si une balise img n’a pas son chevron fermant, elle ira modifier le suivant…)

                            Tu vois j'aime beaucoup les expressions régulières, mais c'est typiquement le genre de choses qui me font les éviter dans des cas généraux. Il y a des cas où ça deviens très compliqué d'être fiable et on pose des hypothèses pour ne pas y passer un temps trop long (voir que le problème soit décidable via des expressions régulières).

                            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                            • [^] # Re: Perl

                              Posté par  . Évalué à 3.

                              Pour modifier quelques occurrences, tu vas plus vite à la main.

                              Pour traiter un certain volume, utiliser une regexp un peu approximative et vérifier le résultat après (quitte à restaurer les anciennes versions en cas de mauvaise surprise au premier essai) sera plus rapide et moins pénible.

                              Pour traiter un gros volume, c’est clair, mieux vaut passer un peu de temps pour bétonner son truc.

                              « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

                              • [^] # Re: Perl

                                Posté par  . Évalué à 3.

                                Pour traiter un gros volume, c’est clair, mieux vaut passer un peu de temps pour bétonner son truc.

                                Et pour traiter un vrai gros volumes, tu passes 80% de ton temps à nettoyer les données et gérer les cas foireux.
                                Typiquement dans mon code ce que tu ferais à l'arrache en 1-10 lignes de awk/perl/sed se transforme en 100-2000 lignes de code.

                                • [^] # Re: Perl

                                  Posté par  . Évalué à 3.

                                  Et pour traiter un vrai gros volumes, tu passes 80% de ton temps à nettoyer les données et gérer les cas foireux.

                                  Non, j’équilibre. C’est rentable d’écrire deux lignes de code pour traiter un cas qui se présente une centaine de fois. Ça ne l’est pas s’il s’agit de faire dix lignes de codes pour corriger deux incohérences qui sont de toute façon des erreurs dans les données de départ et que tu pourrais corriger directement dedans.

                                  Typiquement dans mon code ce que tu ferais à l'arrache en 1-10 lignes de awk/perl/sed se transforme en 100-2000 lignes de code.

                                  Que sais-tu de ce que je fais ?

                                  Quand j’ai converti des tables NIS de plusieurs domaines truffées d’incohérences (parce que mal maintenues à la main pendant plusieurs années) en un annuaire LDAP unique avec une seule entrée par utilisateur (pour le compte, les alias mail, l’automount… comme ça, s’il manque quelque chose ça se voit dessus, et quand on supprime le compte, rien ne traîne), j’ai effectivement pris le temps de coder de l’ordre du millier de lignes (de Perl) pour avoir un résultat propre sans avoir besoin d’y revenir.

                                  La contrainte était que je voulais faire des tests avec l’annuaire LDAP avant de passer dessus en production, donc il fallait que je puisse le refaire à partir des tables NIS à jour sans avoir à ajuster des trucs à la main à chaque fois.

                                  Après, pour la question du nombre de lignes de code, ça dépend aussi du choix de langage et d’implémentation qu’on fait.

                                  J’ai eu besoin un jour de comparer des versions de paquets rpm. Pour savoir comment déterminer si une version est plus récente ou pas, j’ai regardé le code de rpm. Plusieurs pages de code C avec incrémentation du pointeur de chaîne caractère par caractère. Moins de vingt lignes pour un équivalent en Perl utilisant des expressions régulières.
                                  Évidemment, il faut passer plus de temps pour écrire une expression régulière correctement que pour écrire une ligne qui contient juste une incrémentation de pointeur ou une comparaison de nombres, mais au final, le temps passé reste quand même bien moindre qu’à se fader des traitements de chaîne à coup d’incrémentation de pointeur et de comparaison caractère par caractère.

                                  « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

                                  • [^] # Re: Perl

                                    Posté par  . Évalué à 3.

                                    Que sais-tu de ce que je fais ?

                                    Absolument rien.

                                    Ça ne l’est pas s’il s’agit de faire dix lignes de codes pour corriger deux incohérences qui sont de toute façon des erreurs dans les données de départ et que tu pourrais corriger directement dedans.

                                    C'est pour ca que je rebondissais simplement sur le "gros volumes". Corriger directement dans des flux qui font plusieurs centaines de millions de lignes par jour tu ne peux pas. D'ailleurs tu ne peux mêmes pas voir les incohérences si tu n'écris pas tout ce code qui anticipe les erreurs. Par ce que la regexp elle va pas matcher, mais tu nen as aucune idée, ni de pourquoi. Il se peut qu'il y ait plusieurs problèmes différents qui apparaissent et tu veux le savoir et le mesurer. Tu veux avoir une indication de quoi chercher. Faire ca a postériori c'est l'enfer et couteux.

                                    Voilà, c'était simplement un petit conseil. Il y a de plus en plus de gens qui débutent dans le traitement des gros volumes et qui arrivent avec une bonne connaissance des shelleries. Je leur dis simplement de se méfier de awk & co. Ca marche super bien pour fouiller à l'arrache, mais leur tendence à la concision t'empêche de faire le vrai job après.

                                    Après, pour la question du nombre de lignes de code, ça dépend aussi du choix de langage et d’implémentation qu’on fait.

                                    Pas tant que ca, la taille du code vient du fait que tu as besoin de detecter, distinguer et remonter toutes les erreurs possibles.

                          • [^] # Re: Perl

                            Posté par  . Évalué à 3.

                            Une version un peu plus fiable et qui traite les balises img coupées sur plusieurs lignes (l’option -0 suivie d’un code octal spécifie le caractère de fin de ligne ; mettre 777, qui n’existe pas, cause le traitement du fichier en bloc plutôt que ligne par ligne) :

                            perl -i.bak -p0777e 's{(<img\s[^<>]*?)\s?/?>}{$1 />}ig' *.html
                            
                            

                            Bonne chance pour faire l’équivalent avec un découpage…

                            « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

                            • [^] # Re: Perl

                              Posté par  . Évalué à 3.

                              Je n'ai jamais dis qu'awk géré tous et ma remarque n'était pas une critique.

                              Mais puisque tu met awk au défit, je pense (je n'ai pas testé) que ça devrait faire l'affaire :

                              awk -F\> 'BEGIN{RS="<";OFS=">";ORS="<"}{if($1~/^img.*[^\/]/){$1=$1."/"}print}'
                              
                              

                              Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                              • [^] # Re: Perl

                                Posté par  . Évalué à 3.

                                Eh bien je l’ai essayé.
                                Ça marche avec une légère différence : j’ai mis des espaces avant les /> et pas toi, mais aussi un bémol plus important : s’il y a déjà un /, ça en rajoute un autre.
                                Mais pour un premier jet, c’est pas mal du tout.

                                Par contre, tu as quand même utilisé une expression régulière, preuve que le découpage a ses limites. Et à ce stade-là, autant tout faire avec la regexp.

                                « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

                                • [^] # Re: Perl

                                  Posté par  . Évalué à 3.

                                  Ça marche avec une légère différence : j’ai mis des espaces avant les /> et pas toi, mais aussi un bémol plus important : s’il y a déjà un /, ça en rajoute un autre.

                                  L'expression régulière ne doit pas correspondre à ce qu'il faut. Ajouter un espace est trivial.

                                  Par contre, tu as quand même utilisé une expression régulière, preuve que le découpage a ses limites. Et à ce stade-là, autant tout faire avec la regexp.

                                  Et toi un découpage ? :) Je ne vois pas de contradiction entre les deux :)

                                  Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

                                  • [^] # Re: Perl

                                    Posté par  . Évalué à 2.

                                    Ajouter un espace est trivial.

                                    En effet.

                                    Et toi un découpage ? :)

                                    Au contraire, j’ai même désactivé le découpage par ligne…

                                    « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

            • [^] # Re: Perl

              Posté par  . Évalué à 5.

              Par exemple si je veux sommer 2 colonnes d'un fichier

              Effectivement, ce n’est pas vraiment plus compliqué, mais un peu plus long.

              Il y a des cas où il est bien meilleur, mais dans la majorité de mes cas d'utilisation, ce n'est pas le cas.

              Je te crois sur parole vu que tu maîtrises manifestement la question, mais on ne doit pas avoir les mêmes cas d’utilisation.
              Pour ma part (et pour les unilignes), j’utilise rarement l’auto-découpage, souvent les expressions régulières (et ce n’est pas un hasard si celles de Perl ont été copiées par d’autres langages), de temps en temps un module, pas forcément un parcours de fichier (ou de l’entrée standard).

              Et il y a l’avantage que quand j’ai a faire un script un peu conséquent, je le fais avec Perl aussi. Toujours un seul outil, avec une seule syntaxe (à quelques détails près : pour une uniligne je ne déclare pas les variables, alors que pour un script j’utilise le mode strict).

              « Le fascisme c’est la gangrène, à Santiago comme à Paris. » — Renaud, Hexagone

              • [^] # Re: Perl

                Posté par  . Évalué à 4.

                Pour ma part (et pour les unilignes), j’utilise rarement l’auto-découpage, souvent les expressions régulières (et ce n’est pas un hasard si celles de Perl ont été copiées par d’autres langages), de temps en temps un module, pas forcément un parcours de fichier (ou de l’entrée standard).

                On a pas les même cas d'utilisation, quand j'utilise awk 90% des fois je découpe mes champs (des fois plus d'une fois en changeant le record separator et le field separator) et il s'agit de manipuler des flux de données texte qu'ils viennent d'un fichier ou d'ailleurs.

                Et il y a l’avantage que quand j’ai a faire un script un peu conséquent, je le fais avec Perl aussi. Toujours un seul outil, avec une seule syntaxe (à quelques détails près : pour une uniligne je ne déclare pas les variables, alors que pour un script j’utilise le mode strict).

                Quasiment dès qu'il s'agit d'un script enregistré dans un fichier, je passe à autre chose qu'awk ou sed, sauf pour certains cas commencé avec awk et où il reste agréable à utiliser, ici je regarde le nombre de connexion simultanées sur un serveur ssh :

                #!/usr/bin/awk -f
                
                BEGIN {
                   count=0;
                }
                
                /session opened/ {
                   count++;
                   active[$3]=1;
                   print $1","length(active)","count;
                }
                
                /session closed/ {
                   delete active[$3];
                }
                
                

                Je ne me suis même pas posée la question de le faire en autre chose (je m'amuserais à coder ça en perl à l'occasion).

                Mon problème quand je script (avec un vrai fichier), c'est que je suis toujours partagé entre du zsh (ou bash éventuellement) et du perl. Ce qui me permet de discriminer les deux c'est ce que j'ai à faire, si j'appelle trop de commande externes (git, mvn ou autre) alors ce seras du shell, si je fais des manipulations un peu trop évoluée pour du shell ce seras du perl (avec use strict; user warnings; et user 5.010; systématiquement).

                Globalement je suis très loin de m'y connaître en perl et j'avoue me sentir un peu bloqué par cpan, je ne sais pas comment distribuer un script simplement qui a besoin d'un module cpan sans devoir faire l'installation du dis module de partout (sachant que même lorsque l'on vire les tests ça prend du temps).

                Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

  • # font font font, les petites marionnettes

    Posté par  . Évalué à 1.

    À la ligne du 1. :

    L'exécutable gawk évolue donc ainsi ainsi :

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.