URL: https://linuxfr.org/forums/programmation-shell/posts/awk-imbrications-de-commandes Title: awk : imbrications de commandes Authors: fycloud Date: 2015年01月14日T11:25:56+01:00 License: CC By-SA Tags: awk Score: 1 Bonjour à toutes et à tous :) Je présente tout d'abord mon faible niveau en programmation, afin que vous puissiez adapter vos réponses, à mon niveau de compréhension :) J'ai un niveau débutante en python (fonctions, boucles, listes...), php (pas script mais plutôt interrogation avec base sql), je me débrouille bien en expressions régulières, en cut et sed. Me sont inconnus c, js, javaj, c++. J'avance dans la douleur, et n'ai pas forcément le bon vocabulaire pour trouver réponse sur Google. Je suis également de l'école : je ne demande jamais d'aide, quitte à passer plusieurs jours sur un point virgule. Mais me voici. Je souhaiterais me mettre au awk, car on me dit que c'est plus performant qu'une succession de cut et sed. Ayant un peu de temps, j'ai décidé de m'y mettre en réalisant un programme qui me parserait des logs serveur web. On y retrouve donc des informations telles que : date, heure, ip, méthode, url, user agent, referer, temps de chargement de la page... J'ai réalisé un awk qui me ressort des champs de mes fichiers, que je souhaite séparer par des | afin de les traiter facilement par la suite. Dans mon fichier que je lis, j'utilise comme séparateurs l'espace et le guillemet. Mon programme : Je reformate la date (gensub) puis je l'affiche. La boucle me sert à sortir le user agent, puis j'affiche les autres champs de manière classique. J'utilise une boucle pour m'extraire le "user agent", car ce champ contient des espaces (et c'est aussi mon séparateur). La boucle me permet d'extraire un champs dans un intervalle : entre le champs X et X-N. Sauf que, il y a un autre champs à extraire, qui contient lui aussi des expaces. Du coup, mon awk ne fonctionne plus : ni pour extraire le user agent, ni pour extraire cet autre champs : las modified (de type "TUE, 23 Dev 2015 GMT") Ce que je fais, en mode débrouille, c'est un sed 's/[A-Z][a-z][a-z], \([0-9][0-9]\) \([A-Z][a-z][a-z]\) \([0-9][0-9][0-9][0-9]\) [0-9][0-9]:[0-9][0-9]:[0-9][0-9] GMT/1円2円3円/' Afin de nettoyer le fichier, puis d'y appliquer mon awk. Je souhaiterais tout faire avec mon awk. Je cherche donc à faire un gensub sur ce champs problématique pour remplacer les espaces par des tirets, créer un fichier temporaire, sur lequel j'appliquerai mon awk. OU ALORS. Faire un gensub et appliquer mon awk sur le résultat du gensub, le tout en mémoire. Cette dernière solution poserait des problèmes de lenteur, car mes fichiers à parser peuvent faire plusieurs Go. Je ne sais pas en awk créer un fichier temporaire de travail, et le réutiliser pour enchainer une nouvelle commande. Ou alors utiliser le | pour enchainer des commandes ? Mais on travaille en mémoire non ? Ca risque de saturer. Je laisse mon chef d'oeuvre en bas de mon message. Je vous remercie bien d'avance. Marie ```ruby BEGIN { print "date|ip|get|temps_chargement|domaine|res_code|referer|user_agent|last_modified" } { FS=" |\"" a=gensub(/\[([0-9][0-9])\/([A-Z][a-z][a-z])\/([0-9]{4}):[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/, "\1円\2円\3円","g",9ドル); #date str="" for (x=20; x<=nf-6; x++) { str=str$x }; #user_agent print a"|"6ドル"|" 13ドル"|" $(NF-4)"|" $(NF-5)"|" 16ドル"|"19ドル"|"str"|"$(NF-2) #date ip get chargement domaine res_code referer user_agent lastmodified } ``` Une ligne de log ressemble à ca (passage Googlebot) : Dec 28 04:15:04 champs1 apache[dddddd]: dd.dd.dd.xxx - - [28/Dec/2014:04:15:04 +0100] "GET /url-web/prive-blabla HTTP/1.0" rescode - "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" www.mondomaine.fr tempschargementenchiffres "Mon, 22 Dec 2014 18:38:26 GMT" Si un champ est vide, il est remplacé par un tiret.