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 09/09/2012, à 10:05

arnaud_d

Sed et expressions régulières

Bonjour,

Sed et awk restent ma bête noire. A chaque fois que j'ai besoin de les utiliser je passe deux jours à me prendre la tête, lire tous les tutos que je peux pour au final venir demander de l'aide ici sans jamais progresser.

Cette fois-ci je m'arrache les cheveux, tellement tout ce que je lis sur internet semble me donner raison, mais non, ça ne veut pas fonctionner.

Ma mission: Récupérer une sous-chaine en connaissant le contexte dans la même ligne (mots clés)

En réalité je cherche à isoler une adresse dans un fichier HTML mais pour la localiser je souhaiterais rechercher son contexte (par exemple l'intitulé du lien). Déjà si j'arrivais à faire ce qui suit, ce serait un bon début !

Imaginons que j'aie la phrase "arnaud aime ubuntu" comme puis-je extraire "aime" ?

Solution 1 : j'utilise la substitution

arnaud@arnaud-laptop:~$ echo "arnaud aime ubuntu" | sed -n 's/\<arnaud \>\([a-z]*\)\< ubuntu\>/\1/'

Non ça ne marche pas.

Solution 2 : j'utilise print

arnaud@arnaud-laptop:~$ echo "arnaud aime ubuntu" | sed -n '/\<arnaud \>\([a-z]*\)\< ubuntu\>/ p'

Toujours pas !

Merci à ceux qui voudront bien m'éclairer !

EDIT : j'avais oublié le -n de sed

Dernière modification par arnaud_d (Le 09/09/2012, à 10:11)

Hors ligne

#2 Le 09/09/2012, à 10:51

arnaud_d

Re : Sed et expressions régulières

Bonjour gigiair et merci pour ta réponse si rapide.

Mon problème est générique, je veux par exemple extraire une chaîne de caractère en connaissant ce qu'il y a avant et après.

Exemple :

1. J'ai "0982BonjourUUU" je veux pouvoir récupérer "Bonjour" en connaissant "0982" et "UUU"
2. J'ai "<a href="file.pdf">Mon fichier</a>", je veux pouvoir récupérer "file.pdf" en connaissant "<a href=""et "">Mon fichier</a>""
3. J'ai "adresse : arnaud@ubuntu.com", je veux pouvoir récupérer arnaud" en connaissant "adresse : " et "@ubuntu.com"

merci !

Dernière modification par arnaud_d (Le 09/09/2012, à 10:52)

Hors ligne

#3 Le 09/09/2012, à 10:53

miniSeb

Re : Sed et expressions régulières

arnaud_d a écrit :

En réalité je cherche à isoler une adresse dans un fichier HTML mais pour la localiser je souhaiterais rechercher son contexte (par exemple l'intitulé du lien).

Sans donner la réponse en entier, l'expression régulière à constituer sera de ce genre-ci :

<a href="([^"]+)">INTITULÉ DU LIEN</a>

que l'on peut décortiquer comme suit :

<a href="                            # c'est un lien
([^"]+)">                           # sauvegarde tout ce qu'il y a entre href=" et "> // selon les logiciels, la variable sera nommée \1 ou $1
INTITULÉ DU LIEN                        # l'identifiant qui permet de récupérer la bonne url
</a>                                 #  fin du lien (optionnel)

En fait, ce qui t'intéresse ici dans les expressions régulières est la notion de capture

Dernière modification par miniSeb (Le 09/09/2012, à 10:54)

Hors ligne

#4 Le 09/09/2012, à 11:01

arnaud_d

Re : Sed et expressions régulières

miniSeb a écrit :

En fait, ce qui t'intéresse ici dans les expressions régulières est la notion de capture

Oui c'est tout à fait ça.
J'ai essayé d'adapter ce que tu m'as indiqué à mon exemple mais ça ne marche pas :

arnaud@arnaud-laptop:~$ echo "arnaud aime ubuntu" | sed -n 's/arnaud([a-z]+)ubuntu/\1/'
sed: -e expression #1, char 26: invalid reference \1 on `s' command's RHS

Saurais-tu pourquoi ?

Dernière modification par arnaud_d (Le 09/09/2012, à 11:10)

Hors ligne

#5 Le 09/09/2012, à 11:25

miniSeb

Re : Sed et expressions régulières

De un, l'option -n doit être remplacée par -r.
De deux, tu as oublié les espaces dans ta regex : il n'y a donc pas de match ; donc sed échoue.

echo "arnaud aime ubuntu" | sed -r 's/arnaud ([a-z]+) ubuntu/\1/'

Hors ligne

#6 Le 09/09/2012, à 11:30

credenhill

Re : Sed et expressions régulières

hello
avec awk

echo "arnaud aime ubuntu" | awk '{print $2}'

Hors ligne

#7 Le 09/09/2012, à 11:31

miniSeb

Re : Sed et expressions régulières

Là, ça requiert de connaître la position de l'élément à matcher ; c'est différent de connaître le contexte

Hors ligne

#8 Le 09/09/2012, à 12:14

arnaud_d

Re : Sed et expressions régulières

Merci miniSeb,

Du coup j'ai un autre exemple qui marche :

$ echo "0982BonjourUUU" | sed -r 's/0982([A-Za-z]+)UUU/\1/'
Bonjour

Mais comment faire pour éviter qu'il me renvoie la chaîne entière s'il n'y a pas eu correspondance ?

$ echo "0982BonjourUUU" | sed -r 's/1234([A-Za-z]+)UUU/\1/'
0982BonjourUUU

Parce qu'en réalité ce que je veux c'est extraire : j'utilise la fonction remplacer (s) de façon détournée.

Dernière modification par arnaud_d (Le 09/09/2012, à 12:18)

Hors ligne

#9 Le 09/09/2012, à 12:26

miniSeb

Re : Sed et expressions régulières

Combiné -r et -n (sed -rn)

Hors ligne

#10 Le 09/09/2012, à 12:42

arnaud_d

Re : Sed et expressions régulières

Bon avec tout ça je devrais me débrouiller, je reviens poster si j'ai un soucis.

Merci à tous.

Hors ligne

#11 Le 11/09/2012, à 09:34

arnaud_d

Re : Sed et expressions régulières

Re-bonjour,

Pourriez-vous me dire pourquoi aucun des deux exemple suivant ne me permet pas d'extraire "aime" s'il vous plait ?

$ echo "olshfgolhsarnaudaimeubuntulfdjhsjfg" | sed -nr 's/[.+]arnaud(.+)ubuntu[.+]/\1/'
$ echo "olshfgolhsarnaudaimeubuntulfdjhsjfg" | sed -nr 's/.+arnaud(.+)ubuntu.+/\1/'

Merci !

Dernière modification par arnaud_d (Le 11/09/2012, à 09:34)

Hors ligne

#12 Le 11/09/2012, à 14:30

aduxas

Re : Sed et expressions régulières

Je pense qu'il faut omettre l'option -n, mais plus important, [.+] demande l'occurence d'un point ou d'un signe plus.  Ni l'un ni' lautre n'est présent dans la chaine.  veux-tu dire .+ tout court, c.a.d au moins un caractere ?

EDit:  en gros:

sed -r 's/.+arnaud(.+)ubuntu.+/\1/'

Si tu utilises sed -n, il faut imprimer explicitement avec la commande "p"

Dernière modification par aduxas (Le 11/09/2012, à 14:35)

Hors ligne

#13 Le 11/09/2012, à 15:31

arnaud_d

Re : Sed et expressions régulières

Excellent ! Merci
Comme je le disais plus haut, je préfère ne rien avoir en retour s'il n'y a pas match.

Donc ceci est parfait pour moi :

echo "olshfgolhsarnaudaimeubuntulfdjhsjfg" | sed -rn 's/.+arnaud(.+)ubuntu.+/\1/p'

Je comprend peu à peu...

Hors ligne

#14 Le 13/09/2012, à 21:10

arnaud_d

Re : Sed et expressions régulières

Je reviens simplement vous remercier pour votre aide car la "maitrise" (restons modeste tout de même) de sed m'ouvre des portes incroyables. J'ai vraiment l'impression d'avoir passé un step. Je suis devenu un g33k, un vrai.

Pour preuve, je voudrais m'acheter la bio de Steve Jobes sur mon Kindle mais j'attends de voir si le prix ne baisse pas un peu. Admirer ce que l'usage de sed m'a permis de faire : mon ordinateur va tout seul sur amazon.com et me dit si le prix à baissé. C'est génial !

#!/bin/sh

old_price=$((`cat price.txt | tail -n 1`))

new_price=$((`wget "http://www.amazon.fr/Steve-Jobs-ebook/dp/B004W2UBYW" -O - -o /dev/null \
    | grep "EUR " -m 2 \
    | tail -n1 \
    | sed -e 's/^[ \t]*//' \
    | sed -nr 's/EUR (.*)/\1/p' \
    | sed -nr 's/(.*),(.*)/\1\2/p'`))

real_price=`echo "$new_price" | sed -nr 's/(.*)(.{2})/\1.\2/p'`

if [ $new_price -ge $old_price ] ;
then
    notify-send "Steve Jobes" "UP OR EQUAL : $real_price €";
    echo "Steve Jobes : no change" | espeak -v en
else
    notify-send "Steeve Jobes" "DOWN : $real_price €";
    echo "HEY ! The price of the book about Steve Jobes has decreased, it costs now $real_price euros" | espeak -v en -s 200
fi

Dernière modification par arnaud_d (Le 13/09/2012, à 21:12)

Hors ligne

#15 Le 13/09/2012, à 22:59

aduxas

Re : Sed et expressions régulières

Essaye de comprendre les exemples de manip de tampons sur http://www.gnu.org/software/sed/manual/sed.html.  Si tu arrives à tout suivre, j'ai quelques questions pour toi smile

Sinon,

cat fichier | tail -n 1

fait un peu maladroit.  pas besoin de cat; tail prend un nom de fichier aussi (ou plusieurs).  Puis, il n'y a pas besoin d'invoquer sed 2x; une seule est plus efficace:

sed -nr -e 'commande1' -e 'commande2'

  ou encore

sed -nr 'commande1;commande2'

Beau petit script.  Fais-le passer commande en-dessous d'un certain seuil tongue

Hors ligne

#16 Le 14/09/2012, à 06:51

arnaud_d

Re : Sed et expressions régulières

Merci aduxas, je savais que ce n'était pas parfait et qu'il devait bien y avoir un moyen de cumuler les sed.

Après, l'idée de récurer le prix dans un fichier n'est pas terminée, il manque l'écriture du nouveau prix (un petit echo "$new_price" >> price.txt devrait faire l'affaire).

Je vais aussi essayer de lui faire commander, je vais m’entraîner sur des ebooks gratuit sinon ça va me coûter cher smile

Hors ligne