Slt,
J'ai un fichier dont le contenu est le suivant :
02.086
02.095
02.087
02.080
02.080
02.093
02.090
02.085
04.176
03.083
05.252
03.094
03.095
04.095
j'aimerais pouvoir faire la somme d'une ligne donnée comme point de départ et une ligne comme point d'arrivée (pas forcément la dernière ), genre somme de la ligne 7 à 15 . Quelqu'un saurais comment le faire via awk ?
merci
# Dur
Posté par Pascal Terjan (site web personnel) . Évalué à 5.
Il n'y a que 14 lignes donc pas de ligne 15 :)
[^] # Re: Dur
Posté par Pascal Terjan (site web personnel) . Évalué à 6.
En fait juste:
[^] # Re: Dur
Posté par Michaël (site web personnel) . Évalué à 3.
Voilà, et si tu veux glisser ça dans un script shell pour pouvoir t'en resservir tu peux partir de cela:
[^] # Re: Dur
Posté par eastwind☯ . Évalué à 2. Dernière modification le 16 août 2012 à 07:46.
merci juste ce dont j'avais besoin, une chose que je ne comprends néanmoins pas c'est le comportement suivant :
j'ai dans un script bash utilisé awk de cette manière
Il me retourne néanmoins la somme total des lignes au lieu de se contenter de me retourner la somme entre la variable début et fin
Une explication ?
[^] # Re: Dur
Posté par apkwa . Évalué à 1.
C'est parce que ta première expression sera vraie jusqu'à la fin de ton fichier (le
NR>=$deb
), donc leNR==$fin
ne la stoppera pas.Si tu veux utiliser cette forme, c'est:
awk 'NR==$deb,NR==$fin{...
[^] # Re: Dur
Posté par tiot (site web personnel) . Évalué à 4.
Bon déjà il faut comprendre la syntaxe :
pat1 , pat2 {code} : http://www.gnu.org/software/gawk/manual/gawk.html#Ranges
pour chaque ligne il test si pat1 est vrai, si il est vrai alors il exécute le code à chaque ligne jusqu'à que pat2 soit vrai.
Donc il faut que NR>=$fin pour qu'il commence à incrémenter la variable x, et il finira lorsque que NR==$debut. Ce qui veut dire si $début=2 et que $fin=4 alors la condition NR>=$fin sera vrai à partir de la ligne 4 mais par contre tu n'auras jamais NR==$debut (puisque NR sera toujours suppérieur à 4 et donc à 2). Et même si tu t'amuse à avoir un début plus grand que la fin, comme NR>=$fin sera vrai à la ligne suivante il va nécessairement traiter toutes les lignes jusqu'à la fin
Donc ton code additionne tous ce qui est plus grand que $fin sans jamais s'arrêter.
Maintenant lorsque tu mets $fin dans un awk il ne va pas chercher par magie la variable bash correspondante (c'est expliqué dans tous les tutos, même les plus petits) il va faire :
- interprétation de la variable fin, je ne le trouve pas donc je le remplace par 0 ce qui donne $0
- interprétation de $0 c'est à dire toute la ligne
Donc ton code correspond à :
awk 'NR>=$0,NR==$0{x+=$0;}END{print x}'
ce qui fonctionne encore moins et ne correspond pas du tout à ce que tu voulais faire.
Si tu veux garder ta méthode tu dois plutôt faire :
awk -v fin=$fin -v debut=$debut 'NR==debut,NR==fin {x+=$0} END {print x}'
[^] # Re: Dur
Posté par eastwind☯ . Évalué à 2.
merci pour l'explication, faut dire que je commence à peine awk :)
[^] # Re: Dur
Posté par Michaël (site web personnel) . Évalué à 3.
Je te conseille vivement de t'abonner à
comp.unix.shell
tu apprendras très vite.[^] # Re: Dur
Posté par eastwind☯ . Évalué à 2. Dernière modification le 17 août 2012 à 21:21.
ok vais faire un tour .
Je me demandais si à part awk et sed, il y avait d'autres utilitaires necéssaire qui sont satellites à bash (dans le meme ordre d'idées que le coreutils)
(par exemple je ne compte pas apprendre perl, car je souhaite simplement me focaliser sur le shell bash et ses outils satellites comme awk et sed). Au fait, est ce que le binutils est nécessaire pour le script bash alors qu'on ne fait pas de dev ?
[^] # Re: Dur
Posté par Michaël (site web personnel) . Évalué à 3. Dernière modification le 17 août 2012 à 22:11.
Apparemment tu partages ma tendance à utiliser l'outil le plus simple qui te permet de faire le travail (car tu préfères apprendre AWK que PERL). Comme bash est un gros shell bien gras, tu peux réfléchir à apprendre sh plutôt que bash. L'avantage est que tu programmeras de façon un peu plus portable — ce qui peut toujours s'avérer utile. Pour la programmation, le gros plus de bash, c'est les tableaux… quelque part j'ai envie de dire que le shell ne sert pas à programmer, mais à décrire un workflow, et que le besoin de tableau témoigne d'un problème qui ne doit pas être résolu dans le shell.
En gros l'idée est que si tu utilises beaucoup ton tableau, il vaut peut-être mieux écrire un petit outle pour résoudre ton problème. Sinon, tu peux très bien le coller dans un fichier, voire dans un dossier.
Ce livre est souvent controversé, mais je te le recommande tout de même: Unix shell programming de Lowell Jay Arthur (2nd édition, c'est important car souvent dans ce genre de livre, les éditions varient substantiellement). Ce livre est très imprégné de la philosophie Unix et si tu le comprends bien tu sais bien à quoi sert le shell. Le point clef est que le shell sert à décrire un workflow et que le programme que tu coordonnes (avec des pipes) doivent travailler sur une représentation commune des données, la plus simple possible. (XML et JSON sont beaucoup trop complexes!)
Exemples:
— onsgmls (James Clark) permet de passer d'un SGML à une version validée et facile à traiter en shell (chaque élément, attribut, etc. apparaît sur sa propre ligne).
— noweb (Norman Ramsey) utilise un format trivial pour pouvoir piper ses données vers un filtre unix donné par l'utilisateur. (Ce qui au passage te fait une source d'exemples de scripts awk.)
Le point clef de la programmation shell est donc la création de programmes élémentaires qui travaillent sur une représentation commune des données, si possible assez simple pour éventuellement être travaillée avec sed, awk, … (cela évite d'avoir à coder des analogue de awk et sed pour la représentation en question).
Les défauts de la plupart des gens:
— sous-utilisation du système de fichiers (le plus simple pour implémenter une table associative est d'utiliser le système de fichiers, Lowell Jay Arthur explique ça très bien).
— sous-utilisation des pipes nommés pour les IPC.
— utilisation de echo lorqu'il faut utiliser printf (echo sert à afficher un message pour l'utilisateur, tout le reste doitr être géré par printf).
Quelques conseils pour se simplifier la vie:
— pour toutes tes interpolations de type backquote un tant soit peu compliquée, écris une fonction auxiliaire: tu éviteras toutes sortes de migraines liées aux échappements et aux quotes!
— cale toutes tes boucles
while read
dans une fonction à part, cela te simplifiera aussi la vie!En gros les thématiques de bases sont:
fichiers: date (pour les noms horodatés), mv, cp, rm, tar, find, xargs, mktemp ou sa variante qui marche.
base de données: join, paste, etc. (pour préparer ton input à awk! et trop souvent méconnus)
filtres: sort, sed, awk, cut, head, tail, grep.
portabilité: command.
make
Ensuite viennent les outils correspondant au domaine de ton problème:
unix: stat, ps, id, /etc/passwd, etc.
…
Bon courage et amuse-toi bien!
(PS la seconde édition du livre de Lowell Jay Arthur est complètement obsolète — je crois qu'elle parle de System V si bien qu'aucun des exemples du livre ne marche directement, cela fait travailler!)
[^] # Re: Dur
Posté par tiot (site web personnel) . Évalué à 2.
oui en bash pour le traitement des fichiers c'est surtout awk et sed (qui sont des langages de programmation à eux tout seul).
Pour les autres commandes il faut juste savoir ce qu'elles font et avoir un peu d'astuce pour les combiner de la meilleur façon possible. La page wikipedia http://fr.wikipedia.org/wiki/Commandes_Unix présente déjà une bonne base.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.