Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Ecrire script awk trop compliqué pour moi

10 réponses
Avatar
helia
Bonjour,

Quelqu'un peut-il m'aider à créer un petit programme awk pour extraire d'un fichier les paragraphes qui commencent par define service{ et qui se terminent par } qui contiennent la chaine TOTO. J'ai essayé ceci mais le fichier résultat est vide.
cat extract.awk
/^ *\#/ { next }
/}/ { indic=0 }
/define *service.*{/ { indic=1 }
indic==1 && /host_name *TOTO/ { indic=2 }
indic==2 { print $0 }

J'ai exécuté le script extract.awk
extract.awk ficall.txt > ficout
Le fichier résultat est vide

Merci d'avance pour votre aide

10 réponses

Avatar
talon
helia wrote:
Bonjour,

Quelqu'un peut-il m'aider à créer un petit programme awk pour extraire d'un
fichier les paragraphes qui commencent par define service{ et qui se terminent
par } qui contiennent la chaine TOTO. J'ai essayé ceci mais le fichier résultat
est vide.
cat extract.awk
/^ *#/ { next }
/}/ { indic=0 }
/define *service.*{/ { indic=1 }
indic==1 && /host_name *TOTO/ { indic=2 }
indic==2 { print $0 }

J'ai exécuté le script extract.awk
extract.awk ficall.txt > ficout
Le fichier résultat est vide

Merci d'avance pour votre aide



Voici quelque chose qui est loin de faire ce que tu demandes, mais en
fait une petite partie


/^ *#/ { next }
/define *service.*{/ { if ( match($0,/TOTO/) ) { split($0,array,"}") ;print array[1] "}" } }

comme on le voit ici

niobe% awk -f ex.awk
hjk
define service { hjk TOTO hjlk} hkl
define service { hjk TOTO hjlk}

Si le paragraphe est multiligne, je ne sais pas comment il faut faire.

--

Michel TALON
Avatar
Marc Boyer
On 2008-11-04, helia wrote:
Quelqu'un peut-il m'aider à créer un petit programme awk pour extraire d'un
fichier les paragraphes qui commencent par define service{ et qui se terminent
par } qui contiennent la chaine TOTO. J'ai essayé ceci mais le fichier résultat
est vide.
cat extract.awk
/^ *#/ { next }
/}/ { indic=0 }
/define *service.*{/ { indic=1 }
indic==1 && /host_name *TOTO/ { indic=2 }
indic==2 { print $0 }

J'ai exécuté le script extract.awk
extract.awk ficall.txt > ficout



Deux questions:
- quelle est ta définition de "paragraphe" ?
- est-ce qu'il peut y avoir des '}' dans tes paragraphes ?

Tu peux poster aussi un exemple représentatif de ficall.txt histoire qu'on
voit mieux ce que tu veux faire.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
Alain Ketterlin
(Michel Talon) writes:

Quelqu'un peut-il m'aider à créer un petit programme awk pour extraire d'un
fichier les paragraphes qui commencent par define service{ et qui se terminent
par } qui contiennent la chaine TOTO.





/^ *#/ { next }
/define *service.*{/ { if ( match($0,/TOTO/) ) { split($0,array,"}") ;print array[1] "}" } }



Il n'y a pas le choix, il faut mémoriser le bloc avant de décider si
on doit l'afficher

/define *service *{/ {
etat = 1;
mem = "";
out = 0;
}
etat == 1 {
if ( $0 ~ /TOTO/ )
out = 1;
mem = mem $0 "n";
}
/ *} */ {
if ( out )
printf("%s",mem);
etat = 0;
}

A peu près, j'ai rien testé.

-- Alain.
Avatar
Marc Boyer
On 2008-11-04, Michel Talon wrote:
helia wrote:
Bonjour,

Quelqu'un peut-il m'aider à créer un petit programme awk pour extraire d'un
fichier les paragraphes qui commencent par define service{ et qui se terminent
par } qui contiennent la chaine TOTO. J'ai essayé ceci mais le fichier résultat
est vide.
cat extract.awk
/^ *#/ { next }
/}/ { indic=0 }
/define *service.*{/ { indic=1 }
indic==1 && /host_name *TOTO/ { indic=2 }
indic==2 { print $0 }

J'ai exécuté le script extract.awk
extract.awk ficall.txt > ficout
Le fichier résultat est vide

Merci d'avance pour votre aide



Voici quelque chose qui est loin de faire ce que tu demandes, mais en
fait une petite partie


/^ *#/ { next }
/define *service.*{/ { if ( match($0,/TOTO/) ) { split($0,array,"}") ;print array[1] "}" } }

comme on le voit ici

niobe% awk -f ex.awk
hjk
define service { hjk TOTO hjlk} hkl
define service { hjk TOTO hjlk}

Si le paragraphe est multiligne, je ne sais pas comment il faut faire.



Jouer avec RS ?
gavarnie|news> cat service.awk
BEGIN { RS="}" }
/define service.*TOTO/{ print $0 "}"; }
gavarnie|news> cat service.txt
define service {
TOTO
titi
}
define service {
TUTU
tata
}
gavarnie|news> awk -f service.awk service.txt
define service {
TOTO
titi
}

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
Jacques L'helgoualc'h
Bonjour,

Le 04-11-2008, Alain Ketterlin a écrit :
[...]
Il n'y a pas le choix, il faut mémoriser le bloc avant de décider si
on doit l'afficher

/define *service *{/ {
etat = 1;
mem = "";
out = 0;
}
etat == 1 {
if ( $0 ~ /TOTO/ )
out = 1;
mem = mem $0 "n";
}
/ *} */ {
if ( out )
printf("%s",mem);
etat = 0;
}

A peu près, j'ai rien testé.



Sed est plus concis --- mais ça ne marchera pas avec des blocs emboîtés,
ou des commentaires pervers :

~ $ cat exemple
# rien
# define service { TOTO }
# rien
define service { TOTO }
#rien
define service {
# rien1
TOTO }
# rien
define service {
TOTO
bla
# rien }
}
# fin

~ $ sed -ne '
/^[^#]*define[[:space:]]+service[[:space:]]*{/{
:A
/define[[:space:]]+service[[:space:]]*{[^}]*TOTO[^}]*}/p
/define[[:space:]]+service[[:space:]]*{[^}]*}/d
N
b A
}
' <exemple
define service { TOTO }
define service {
# rien1
TOTO }
define service {
TOTO
bla
# rien }



--
Jacques L'helgoualc'h
Avatar
Marc Boyer
On 2008-11-04, Jacques L'helgoualc'h <"lhh+news,no_spam"@free.fr.isnt.invalid> wrote:
Bonjour,

Le 04-11-2008, Alain Ketterlin a écrit :
[...]
Il n'y a pas le choix, il faut mémoriser le bloc avant de décider si
on doit l'afficher

/define *service *{/ {
etat = 1;
mem = "";
out = 0;
}
etat == 1 {
if ( $0 ~ /TOTO/ )
out = 1;
mem = mem $0 "n";
}
/ *} */ {
if ( out )
printf("%s",mem);
etat = 0;
}

A peu près, j'ai rien testé.



Sed est plus concis --- mais ça ne marchera pas avec des blocs emboîtés,
ou des commentaires pervers :



Un expert sed sera toujours meilleurs qu'un débutant awk.
Moi qui ne suis ni expert ni débutant en sed et awk, pour des
patern multi-lignes, je préfère franchement awk.
Et généralement aussi, je préfère virer les commentaires avant
de parser sérieusement, et sed suffit largement.

gavarnie|news> sed -e 's/#.*$//g' -e '/^ *$/d' exemple.txt | awk -f service.awk
exemple
define service { TOTO }

define service {
TOTO }

define service {
TOTO
bla
}
gavarnie|news> cat service.awk
BEGIN { RS="}" }
/define service.*TOTO/{ print $0 "}"; }
gavarnie|news>


Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
Jacques L'helgoualc'h
Le 06-11-2008, Marc Boyer a écrit :
On 2008-11-04, Jacques L'helgoualc'h wrote:


[...]
Sed est plus concis --- mais ça ne marchera pas avec des blocs emboîtés,
ou des commentaires pervers :



Un expert sed sera toujours meilleurs qu'un débutant awk.
Moi qui ne suis ni expert ni débutant en sed et awk, pour des
patern multi-lignes, je préfère franchement awk.



Oui, c'est plus facile à (re)lire...

Et généralement aussi, je préfère virer les commentaires avant
de parser sérieusement, et sed suffit largement.

gavarnie|news> sed -e 's/#.*$//g' -e '/^ *$/d' exemple.txt | awk -f service.awk


[...]
gavarnie|news> cat service.awk
BEGIN { RS="}" }
/define service.*TOTO/{ print $0 "}"; }



Élégant, mais ne marche pas sur cet exemple-ci :

# debut
rien
define service { TOTO }
non { rien de rien }
define service {
TOTO }

quelque chose sans accolades

define service {
TOTO
bla
}

autre chose TOTO
define service {
Taratata
}
# fin


~ $ <exemple sed -e '
/^[[:space:]]*$/d
s/#.*$//
' |
awk -v RS="}" '
/define service.*TOTO/{
sub("^.*define service","define service");
print $0 "}n";
}'
define service { TOTO }

define service {
TOTO }

define service {
TOTO
bla
}


--
Jacques L'helgoualc'h
Avatar
Marc Boyer
On 2008-11-06, Jacques L'helgoualc'h <"lhh+news,no_spam"@free.fr.isnt.invalid> wrote:
Le 06-11-2008, Marc Boyer a écrit :
Et généralement aussi, je préfère virer les commentaires avant
de parser sérieusement, et sed suffit largement.

gavarnie|news> sed -e 's/#.*$//g' -e '/^ *$/d' exemple.txt | awk -f service.awk


[...]
gavarnie|news> cat service.awk
BEGIN { RS="}" }
/define service.*TOTO/{ print $0 "}"; }



Élégant, mais ne marche pas sur cet exemple-ci :



En effet.
En fait, sans une spec un peu claire de ce qui est demandé, c'est difficile de
faire une solution.
Et si on complique à loisir la grammaire d'entrée, à un moment, il deviendra
peut-être plus rentable de se tourner vers un vrai parseur...


Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)
Avatar
Cyrille Lefevre
Marc Boyer a écrit :
[snip]
gavarnie|news> sed -e 's/#.*$//g' -e '/^ *$/d' exemple.txt | awk -f ser vice.awk
exemple
define service { TOTO }

define service {
TOTO }

define service {
TOTO
bla
}
gavarnie|news> cat service.awk
BEGIN { RS="}" }
/define service.*TOTO/{ print $0 "}"; }
gavarnie|news>



Bonjour,

a quoi sert le sed ?

awk '
/^[ t](#|$)/ { next }
...
'

Cordialement,

Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%
supprimer "%nospam% et ".invalid" pour me repondre.
Avatar
Jacques L'helgoualc'h
Le 07-11-2008, Cyrille Lefevre a écrit :
Marc Boyer a écrit :
[snip]
gavarnie|news> sed -e 's/#.*$//g' -e '/^ *$/d' exemple.txt | awk -f service.awk




[...]
gavarnie|news> cat service.awk
BEGIN { RS="}" }
/define service.*TOTO/{ print $0 "}"; }
gavarnie|news>



Bonjour,

a quoi sert le sed ?

awk '
/^[ t](#|$)/ { next }
...
'



Avec la redéfinition de RS, ça ne nettoiera plus grand chose --- le sed
nettoie ligne par ligne (mais supprimer les commentaires dans les blocs
sélectionnés n'est pas forcément une bonne idée).

Un truc du genre

awk '
...
gsub("(^|n)[ t]*(#[^n]*|$)","")
...

n'est pas très lisible.
--
Jacques L'helgoualc'h