Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 28/06/2008, à 14:50

redisded

[résolu][bash]Petit souci avec AWK (suite et fin...).

Bonjour à tous, j'ai débuté récemment l'apprentissage des script bash, et je me retrouve depuis hier avec une commande awk qui ne fait pas ce que je souhaite. Je ne parviens pas à trouver la syntaxe correcte grace au net alors je me permet de vous questionner wink

Mon pb est le suivant :
J'ai un fichier composé de plusieurs enregistrements (des paragraphes en fait) séparés par des "%", et je souhaiterais utiliser awk pour n'afficher que le paragraphe qui contient une certaine chaine de caracteres ("?1111" dans l'exemple).

Après de multiples messages, d'erreur, j'ai finalement réussi à intégrer ma condition dans ma commande awk, mais la selection du paragraphe ne se fait pas (tout le fichier est affiché) :

cat "bashfr_new" | awk 'BEGIN{RS="%"} NF==0{next} {if (grep "\?1111" "$0") {print $0} else {next}}'

Si quelqu'un à une idée du problème ou meme une suggestion pour faire cette manip autrement....

Merci d'avance.

Dernière modification par redisded (Le 04/07/2008, à 12:32)

Hors ligne

#2 Le 29/06/2008, à 09:48

Totor

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

voilà, tout simplement :

awk ' /\?1111/ { print $0 }' "bashfr_new"

Dernière modification par Totor (Le 29/06/2008, à 09:49)


-- Lucid Lynx --

Hors ligne

#3 Le 29/06/2008, à 12:33

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

Merci à toi Totor.

Pour info, ta commande n'affiche que la ligne qui contient la chaine de caracteres recherchées.

En faisant un mix de ta commande et de la mienne , j'ai réussi à trouver mon bonheur :

 awk 'BEGIN{RS="%"} NF==0{next} /\?1111/ { print $0 }' "bashfr_new"

Encore merci, j'étais bien en galère et le man AWK est pour le moins indigeste!! wink

Dernière modification par redisded (Le 29/06/2008, à 12:34)

Hors ligne

#4 Le 29/06/2008, à 13:17

guls

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

Bonjour,

En un peu plus simple, ceci ne conviendrait-il pas :

awk -vRS='%' '/\?1111/' 'bashfr_new'

#5 Le 29/06/2008, à 13:44

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

guls a écrit :

Bonjour,

En un peu plus simple, ceci ne conviendrait-il pas :

awk -vRS='%' '/\?1111/' 'bashfr_new'

Ca marche nickel et c'est en effet encore plus simple (si vous aviez vu les ligne à rallonges que j'ai tésté pour essayer d'en arriver la ! roll )

Un grand merci à vous deux !!

Hors ligne

#6 Le 29/06/2008, à 15:17

Totor

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

redisded a écrit :

Merci à toi Totor.

Pour info, ta commande n'affiche que la ligne qui contient la chaine de caracteres recherchées.

En faisant un mix de ta commande et de la mienne , j'ai réussi à trouver mon bonheur :

 awk 'BEGIN{RS="%"} NF==0{next} /\?1111/ { print $0 }' "bashfr_new"

Encore merci, j'étais bien en galère et le man AWK est pour le moins indigeste!! wink

oup's ! désolé... je n'avais pas vu que tu voulais le § roll


-- Lucid Lynx --

Hors ligne

#7 Le 29/06/2008, à 15:19

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

pas grave ta commande m'a dépanné quand meme j'avais plus qu'a compléter wink

Dernière modification par redisded (Le 29/06/2008, à 15:21)

Hors ligne

#8 Le 02/07/2008, à 19:06

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

Bonsoir à tous.

Bon alors j'ai encore un souci avec cette commande alors je me permet d'abuser une fois de plus de vos compétences.

En fait je voudrais savoir comment pouvoir réutiliser des variables présente dans mon script dans la commande awk.

j'ai utilisé par exemple ailleurs dans le script :

awk -v "nb=$nb" 'BEGIN{RS="%\n"} NF==0{next} FNR!=nb{next} {print $0}'

Et cela va bien me chercher le paragraphe correspondant au nombre contenu dans la variable nb.

j'essaye donc pour mon exemple :

awk -v "nb=$numquote" -v "confrep=$confrep" 'BEGIN{RS="%"} NF==0{next} /\?nb/ { print $0 }' "confrep/bashfr_new"

Je voudrais en fait que la chaine de caracteres à rechercher ainsi que le dossier contenant le fichier à parcourir soit les contenus de 2 variable qui auront été défini auparavant.

Malheureusement, dans mon exemple, awk recherche la chaine nb et le dossier confrep, qui ne sont donc pas interprétés comme des variables.

J'ai également essayé différentes variantes avec la commande de guls mais sans succes.

Si une ame charitable a une solution à me proposer, que sa descendance soit bénie sous 10 générations wink

Dernière modification par redisded (Le 02/07/2008, à 19:09)

Hors ligne

#9 Le 02/07/2008, à 20:28

Totor

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

alors, si tu veux utiliser le contenu de la variable nb comme expression régulière, il faut utiliser l'opérande ~ et faire comme ceci :

awk -v "nb=$numquote" -v "confrep=$confrep" 'BEGIN{RS="%"} NF==0{next} $0 ~ "?"nb { print $0 }' "confrep/bashfr_new"

pour ton dossier, je ne vois pas où tu utilises la variable confrep dans le script awk propement dit et le seul endroit est dans le fichier à utiliser par awk. Auquel cas, tu n'as pas besoin de définir une variable pour awk mais à utliser ta variable définie auparavant comme suit :

awk -v "nb=$numquote" 'BEGIN{RS="%"} NF==0{next} $0 ~ "?"nb { print $0 }' "${confrep}/bashfr_new"

Dernière modification par Totor (Le 02/07/2008, à 20:35)


-- Lucid Lynx --

Hors ligne

#10 Le 02/07/2008, à 20:41

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

Totor a écrit :

pour ton dossier, je ne vois pas où tu utilises la variable confrep dans le script awk propement dit et le seul endroit est dans le fichier à utiliser par awk. Auquel cas, tu n'as pas besoin de définir une variable pour awk mais à utliser ta variable définie auparavant comme suit :

awk -v "nb=$numquote" 'BEGIN{RS="%"} NF==0{next} $0 ~ "?"nb { print $0 }' "${confrep}/bashfr_new"

Alors :
- je me suis mal fait comprendre, je n'écris pas un script awk mais un script shell dans lequel se est invoqué cette commande.

- Les deux variables sont prédéfinie dans le script shell mais j'avais cru lire qu'il fallait redeclarer chaque variable dans awk car il ne pouvait acceder aux variables définies avant !
Si je comprend bien ce que tu me dis, je peut appeler les variables créées dans le script grace à la syntaxe ${mavariable}, ce qui serait parfait! je test et te tiens au courant.

EDIT : Ca marche nikel !!!!

1000 fois merci à toi Totor wink

Dernière modification par redisded (Le 02/07/2008, à 20:47)

Hors ligne

#11 Le 02/07/2008, à 21:01

Totor

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

Si je comprend bien ce que tu me dis, je peut appeler les variables créées dans le script grace à la syntaxe ${mavariable}, ce qui serait parfait! je test et te tiens au courant.

Nop nop nop.... ce n'est pas ce que je dis !!!!
je dis que ta variable confrep n'est pas utilisée dans ton script awk.
le script awk est uniquement la partie :

'BEGIN{RS="%"} NF==0{next} $0 ~ "?"nb { print $0 }'

car

"${confrep}/bashfr_new"

correspond à un paramètre de la commande awk et il est donc intérprété par ton shell !!!

Par ailleurs, ceci est faux :

...qu'il fallait redeclarer chaque variable dans awk car il ne pouvait acceder aux variables définies avant !

tu peux très bien accèder à tes variables d'environnement dans ton script awk grace à une variable awk ENVIRON qui contient la liste des valeurs des variables d'environnement. Bien entendu, il est impératif d'effectuer un export de ta variable.

Exemple, ton script peut être écrit de la façon suivante :

export nb
awk 'BEGIN{RS="%"} NF==0{next} $0 ~ "?"ENVIRON["nb"] { print }' "${confrep}/bashfr_new"

Dernière modification par Totor (Le 02/07/2008, à 21:02)


-- Lucid Lynx --

Hors ligne

#12 Le 02/07/2008, à 22:48

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

oki !
merci à toi pour toutes ces précisions. cette partie du script est définitivement codé je pense maintenant et ce grace à vos précieux conseils, merci à tous.

Hors ligne

#13 Le 03/07/2008, à 17:03

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

redisded a écrit :

cette partie du script est définitivement codé je pense maintenant...

... euuh bah en fait je devrais arreter de penser wink

Bon je crois que j'ai trouvé la commande la plus relou à écrire de toute ma (minuscule) vie de codeur, et elle est pas pres d'être détronnée !

Alors, grace à vos excellents conseils, j'ai dans mon script la ligne suivante :

quote=$(awk -v "nb=$numquote" 'BEGIN{RS="%\n"} NF==0{next} $0 ~ "?"nb { print $0 }' "${confrep}/bashfr_new")

je pensais l'affaire réglée mais je viens de me rencontre qu'il subsiste un probleme :

Si je fais une recherche sur le numéro 70 par exemple, awk me selectionne également les paragraphes contenant le numéro 700, 701, 702 ... (normal me direz-vous, c'est exactement ce que tu lui demande wink )

J'ai donc essayé diverses syntaxes comme :

quote=$(awk -v "nb=$numquote" 'BEGIN{RS="%\n"} NF==0{next} $0 ~ "?"^nb$ { print $0 }' "${confrep}/bashfr_new")

ou

quote=$(awk -v "nb=$numquote" 'BEGIN{RS="%\n"} NF==0{next} $0 ~ "?"^[nb]$ { print $0 }' "${confrep}/bashfr_new")

mais bien sur, il ne veut rien entendre et me renvoi systématiquement une erreur de syntaxe roll.

Si un des dompteurs d'awk que vous êtes pouvait m'aider à finaliser cette f*!#tue ligne !

(Promis apres j'arrete de vous embeter avec ca wink )

Dernière modification par redisded (Le 03/07/2008, à 17:33)

Hors ligne

#14 Le 03/07/2008, à 17:33

Totor

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

Qu'est-ce qui différencie ton 70 au 700, 701, 702... dans le reste de ta ligne ?
Plus généralement, qu'est-ce qui fait l'unicité de ton nb ?
Il y a t'il des caractères non numérique après nb ?
auquel cas :

quote=$(awk -v "nb=$numquote" 'BEGIN{RS="%\n"} NF==0{next} $0 ~ "?"nb"[^0-9]" { print $0 }' "${confrep}/bashfr_new")

devrait suffir.


-- Lucid Lynx --

Hors ligne

#15 Le 03/07/2008, à 17:43

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

bon pour répondre à toutes tes questions en meme temps, le fichiers est en fait le fichier fortune de bashfr : http://www.bashfr.org/bashfr_fortunes (attention, l'ouverture de ce lien me fait planter firefox, tu devrais peut-etre le "wget" )

et donc je recherche un n° de quote (qui sera fourni par l'utilisateur) dans la derniere ligne de chaque paragraphes :

---www.bashfr.org/?xxxx

donc il n'y aura jamais rien derriere, et rien ne différencie le reste de la ligne à part le n° de la quote justement.
Pour ce qui fait l'unicité du nb ... euuuhh ... j'comprend pas ce que tu me demande, désolé roll

En fait, je voudrais juste pouvoir lui signifier que la ligne à chercher fini pa nb, je pense que c'est par là qu'il faut aller mais je trouve pas le chemin wink
merci à toi de te pencher une fois de plus sur mes péripeties en tout cas wink

Dernière modification par redisded (Le 03/07/2008, à 17:46)

Hors ligne

#16 Le 03/07/2008, à 17:51

Totor

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

si nb est vraiment à la fin de ton paragraphe alors ça suffit pour déterminer son unicité.

~ (tilde) permet d'effectuer des comparaisons de chaines en les considérant comme expressions régulières. Il te faut donc construire ton expression et la comparer avec ton paragraphe ($0 dans ton cas).

Ton expression recherchée est donc ?<valeur variable nb><fin paragraphe>. Ce qui donne :

quote=$(awk -v "nb=$numquote" 'BEGIN{RS="%\n"} NF==0{next} $0 ~ "?"nb"$" { print $0 }

Dernière modification par Totor (Le 03/07/2008, à 17:53)


-- Lucid Lynx --

Hors ligne

#17 Le 03/07/2008, à 18:07

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

merci à toi Totor, malheureusement ton exemple ne fonctionne pas (j'avais tésté il me semble wink ).

Dans ce cas, awk ne selectionne aucune ligne, j'ai l'impression selon mon log qu'il recherche tout simplement le caractère $ apres le numéro...

EDIT : euuh petite question au cas ou : quand je spécifie "%\n" comme étant mon séparateur d'enregistrements, du coup il ne fait plus parti d'un paragraphe? (i.e il ne peut pas etre interprété comme le dernier champ d'un enregistrement? )

EDIT 2 : Sinon au pire je vais rajouter un coup de sed sur tout le fichier pour rajouter un $ apres chaque lignes qui contient le numéro de la quote, et ta ligne fonctionnera lol  ---> ][

Dernière modification par redisded (Le 03/07/2008, à 18:44)

Hors ligne

#18 Le 03/07/2008, à 18:58

Totor

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

d'après ton post de 17h03, tu as essayé
"?"^nb$
et
"?"^[nb]$

mais pas
"?"nb"$"

donc essaie (j'ai testé et ça marche tongue)


-- Lucid Lynx --

Hors ligne

#19 Le 03/07/2008, à 19:26

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

bah oui j'ai bien retesté quand tu me l'a dit pour etre sur mais je me retrouve avec une variable vide ... je vais ré-essayer et me pencher sur le log pour voir...

Hors ligne

#20 Le 03/07/2008, à 19:35

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

comprend pas ....

en mettant dans ma ligne "$", jobtiens dans mon log :

++ awk -v nb=7524 'BEGIN{RS="%\n"} NF==0{next} $0 ~ "?"nb"$" { print $0 }' /home/red/.bashfr/bashfr_new
+ quote=

mais des que je le supprime, jobtiens :

++ awk -v nb=7524 'BEGIN{RS="%\n"} NF==0{next} $0 ~ "?"nb { print $0 }' /home/red/.bashfr/bashfr_new
+ quote='fef> j'\''comprends pas sur PES rothen il est pas bon, alors que c'\''tait le meilleur parisien cette année

marco> ...et Dieu inventa la relativité
-- http://www.bashfr.org/?7524'

Alors que ca marche chez toi, grrrrrrrrrrrr.

tu as essayé sur le meme fichier?

Hors ligne

#21 Le 03/07/2008, à 20:45

Totor

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

mea culpa : je n'avais pas testé avec le même fichier mais avec un fichier que j'avais créé !

je viens de le faire avec ton fichier et voici ce qu'il faut mettre :

quote=$(awk -v "nb=$numquote" 'BEGIN{RS="\n%\n"} NF==0{next} $0 ~ "\?"nb"$" { print $0 }' "${confrep}/bashfr_new")

Attention, mets bien \n%\n comme séparateur de paragraphe (le 2ème \n est obsolète mais il te permet d'épurer ton paragraphe)
de même, il faut absolument que ton fichier fortune soit au format unix.
c'est con mais en faisant un copier coller depuis mozilla vers kate, il me l'a enregistré au format dos et j'ai passé 10 min à comprendre pourquoi j'avais des

awk: program limit exceeded: maximum number of fields size=32767
        FILENAME="bash_fortunes.txt" FNR=1 NR=1

hmm

Dans ton cas, ce qui n'allait pas dans ton test était ton séparateur : %\n
en effet, ta fin de paragraphe contenait donc un \n et ce n'est donc pas ton numquote qui était en fin de paragraphe.
avec %\n comme séparateur, il aurait fallu mettre :

quote=$(awk -v "nb=$numquote" 'BEGIN{RS="%\n"} NF==0{next} $0 ~ "\?"nb"\n$" { print $0 }' "${confrep}/bashfr_new")

mais ça te laisse un retour chariot en fin de paragraphe. c'est pourquoi, je te propose d'utiliser \n%\n comme séparateur.

Dernière modification par Totor (Le 03/07/2008, à 20:47)


-- Lucid Lynx --

Hors ligne

#22 Le 03/07/2008, à 20:51

redisded

Re : [résolu][bash]Petit souci avec AWK (suite et fin...).

yeeeeeeeeeeeeeeeeeees !!!!!!

1000000000000 fois merci à toi de t'etre pris la tete pour trouver d'ou ca venait !!!

Tu déchire tout ; ca marche impec !! wink

En plus, j'avais dépassé l'histoire du séparateur depuis longemp, ca ne me serait jamais venu à l'ésprit roll

Merci pour ton aide précieuse (tu aura une place de choix dans la partie remerciements du script wink )

Dernière modification par redisded (Le 03/07/2008, à 20:54)

Hors ligne