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 11/01/2010, à 21:48

jj16

Sed résultat inattendu !

bonsoir

J'ai testé l'utilitaire sed avec la configuration suivante  sed /regex1/,/regex2/d fichier
d'après ce que j'ai pu lire celà devrait sélectionner, pour la commande, les lignes entre la première qui satisfait l'expression régulière regex1 et la première qui satisfait l'expression régulière regex2

j'ai testé sur le fichier d'essai suivant :   sed /toto/,/montagne/d fichier

toto
TOTO
toto
titi
titimachin
totomachin           celà m'a donné comme résultat :     machin   pour moi la commande airait dû affecter que les 8
machin                                                                           tutu         première ligne !
montagne                                                                      tooto
machine
tutu
tooto
machintoto
truc1
word2

je m'explique pas du tout ce résultat.
si quelqu'un pouvait méclairer


jj16

Hors ligne

#2 Le 11/01/2010, à 22:03

sputnick

Re : Sed résultat inattendu !

Attention, toto matche toto, totomachin, machintoto !
Tu doit être plus précis dans ta regex(p). /pattern/ c'est comme un grep
Utilise les ^ et $ par exemple ( debut et fin de ligne respectivement )


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#3 Le 11/01/2010, à 22:19

jj16

Re : Sed résultat inattendu !

pour moi toto est rencontré à la première ligne et montagne à la huitième et je croyais que la commande n'irait pas chercher plus loin

Hors ligne

#4 Le 11/01/2010, à 22:24

skingrapher

Re : Sed résultat inattendu !

bonsoir,
ce ne serait pas plutôt çà dont tu aurais besoin ?

sed /machine/,/word2/ fichier

L'expression que tu as formulée n'est pas une sélection pour afficher les lignes, mais pour les retrancher de l'affichage.


Je suis un obsédé textuel. J'aime trop le LaTeX.

Hors ligne

#5 Le 11/01/2010, à 22:30

jj16

Re : Sed résultat inattendu !

slt skingrapher

en fait pour moi la commande aurait supprimer les 8 lignes entre  le premier toto rencontré et
la première montagne rencontré
en fait ça marche si je fait : sed /^toto/,/^montagne/d fichier
mais je comprend pas pourquoi  : sed /toto/,/montagne/d fichier ne fonctionne pas

Hors ligne

#6 Le 11/01/2010, à 22:46

nesthib

Re : Sed résultat inattendu !

sed '/^toto$/,/montagne/d' fichier

fonctionne très bien wink


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#7 Le 11/01/2010, à 22:52

jj16

Re : Sed résultat inattendu !

ok ça fonctionne mais ça m'explique pas pourquoi   sed /toto/,/montagne/d fichier  ne fonctionne pas la première occurrence trouvé est toto sur la premère ligne !

je sais je sais je suis un peu têtu mais je ch à comprendre

Hors ligne

#8 Le 11/01/2010, à 22:58

jj16

Re : Sed résultat inattendu !

ah ça y est j'ai trouvé l'explication !

/exp1/,/exp2/

    * Toutes les lignes comprises entre exp1 et exp2, y compris les lignes contenant exp1 et exp2. Si l'intervalle contenant les 2 expressions se répète plusieurs fois, Sed appliquera les instructions à chaque intervalle successivement. Si toutefois exp2 n'est pas trouvée, les instructions sont appliquées à chaque ligne en partant de exp1 et ce jusqu'à la fin du fichier.

certaines explications sur sed ne parlent pas de la répétion de l'interval !
ça sert d'être têtu parfois !

En tout ca merci à tous de vous être penché sur mon pb !

jj16

Hors ligne

#9 Le 11/01/2010, à 23:50

nesthib

Re : Sed résultat inattendu !

effectivement j'ai lu un peu vite et je ne vois pas la solution pour éviter cela en sed.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#10 Le 12/01/2010, à 14:31

Totor

Re : Sed résultat inattendu !

nesthib a écrit :

effectivement j'ai lu un peu vite et je ne vois pas la solution pour éviter cela en sed.

Voilà:

sed -n '/exp1/ { :deb; s/exp2/&/; t fin; N; b deb; :fin; p } ' fichier

-- Lucid Lynx --

Hors ligne

#11 Le 12/01/2010, à 20:34

nesthib

Re : Sed résultat inattendu !

@Totor : ta commande ça ne revient pas à ça ?

sed -n '/exp1/,/exp2/p'

moi je comprends :
- si tu trouves exp1
   - tant que tu ne trouves pas exp2 (substitution nulle échouée) tu ajoutes la ligne suivante au buffer
   - si tu arrives à exp2 tu affiches le buffer (qui contient donc toutes les lignes que tu ne veux pas)

ce qu'il veut est supprimer le premier pattern inclus entre les lignes contenant exp1 et exp2 (même si on trouve ultérieurement exp1 et/ou exp2)


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#12 Le 12/01/2010, à 21:04

Totor

Re : Sed résultat inattendu !

Pour répondre  à ta 1ère question :
non, ce n'est pas équivalent. Ma syntaxe affiche un résultat uniquement si les lignes contenant exp1 et exp2 existent.

Pour faire ce qu'il souhaite, ce ne doit pas être difficile avec ce que j'ai donné.
Je n'ai pas le temps ce soir (je posterai demain)


-- Lucid Lynx --

Hors ligne

#13 Le 13/01/2010, à 01:31

nesthib

Re : Sed résultat inattendu !

c'était pas très compliqué en fait!

sed '0,/exp2/{/exp1/,$d}' fichier

maintenant si on ne veut supprimer que la nième occurrence ?


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#14 Le 13/01/2010, à 08:39

Mpok

Re : Sed résultat inattendu !

J'ai appris quelque chose à la lecture de ce sujet... big_smile
(mon utilisation de sed était jusque là très basique. Je découvre que c'est bien plus puissant...).

Hors ligne

#15 Le 13/01/2010, à 10:11

nesthib

Re : Sed résultat inattendu !

Mpok a écrit :

mon utilisation de sed était jusque là très basique. Je découvre que c'est bien plus puissant...

et encore t'as rien vu! Un tetris fait en sed → http://uuner.livejournal.com/55238.html (russe)


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#16 Le 13/01/2010, à 12:38

Mpok

Re : Sed résultat inattendu !

@nesthib : VERY NICE indeed !!! (lol, i'm FAR beyond...)

Hors ligne

#17 Le 14/01/2010, à 19:07

sputnick

Re : Sed résultat inattendu !

nesthib a écrit :
Mpok a écrit :

mon utilisation de sed était jusque là très basique. Je découvre que c'est bien plus puissant...

et encore t'as rien vu! Un tetris fait en sed → http://uuner.livejournal.com/55238.html (russe)

@nesthib : Jesus Marie Joseph ! Holy shit !

Ca fais mal au crâne big_smile

@Totor : Peux tu expliquer les points les plus importants de ta syntaxe ?
{ }  == regroupement de commandes I presume ?

Quid de :deb, t fin... ? Variables ? Constantes ?

Dernière modification par sputnick (Le 14/01/2010, à 19:08)


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#18 Le 14/01/2010, à 20:49

nesthib

Re : Sed résultat inattendu !

sed -n '/exp1/ { :deb; s/exp2/&/; t fin; N; b deb; :fin; p } ' fichier

sed → lit "fichier" ligne à ligne et applique les commandes
-n → pas d'affichage par défaut des lignes
/exp1/ → si la ligne comporte "exp1" exécute {…}
:deb → étiquette "deb"
; → commande suivante
s/exp2/&/ → substitue exp2 par lui même
t → si la substitution précédente à réussi va à l'étiquette "fin"
N → ajoute la ligne suivante au tampon
b deb → va à l'étiquette "deb"
:fin → étiquette "fin"
p → affiche la ligne

donc pour résumer tu n'affiches rien
à partir du moment où tu trouves "exp1" et tant que tu ne trouves pas "exp2" tu ajoutes les lignes au tampon
si tu trouves "exp2" tu affiches le tampon.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#19 Le 15/01/2010, à 02:05

Totor

Re : Sed résultat inattendu !

Merci nesthib pour les explications, c'est parfait wink
désolé, ces derniers temps je n'ai que très peu de temps à consacrer au forum
d'ailleurs, je n'ai pas encore eu le temps de me pencher sur ta question (maintenant si on ne veut supprimer que la nième occurrence ?) qui est me semble un vrai défi à relever wink


-- Lucid Lynx --

Hors ligne

#20 Le 15/01/2010, à 09:48

nesthib

Re : Sed résultat inattendu !

Totor a écrit :

Merci nesthib pour les explications, c'est parfait wink
désolé, ces derniers temps je n'ai que très peu de temps à consacrer au forum
d'ailleurs, je n'ai pas encore eu le temps de me pencher sur ta question (maintenant si on ne veut supprimer que la nième occurrence ?) qui est me semble un vrai défi à relever wink

De rien wink et pas de soucis moi aussi je suis bien occupé en ce moment!
Pour ce qui est de cette histoire de nième occurence je n'ai pas eu le temps de chercher non plus mais il est vrai que ça risque de na pas être facile! (peut-être en utilisant le tampon d'échange) ce qu'il manque c'est de pouvoir utiliser des variables.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#21 Le 15/01/2010, à 10:19

nesthib

Re : Sed résultat inattendu !

une solution à l'arrache (et sûrement pas optimale) m'est venue en tête pour par exemple afficher le 2ème pattern
problème, pour l'instant il faut 2 sed

echo -e 'abc\ndef\n1\nghi\njkl\nabc\ndef\n2\nghi\njkl\nabc\ndef\n3\nghi\njkl' | sed -n -e '/def/{:deb ; s/ghi/&/; t fin; N; b deb; :fin; {s/\n/\\#/g;H;p}}' | sed -n '2s/\\#/\n/gp'

GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#22 Le 16/01/2010, à 18:52

Totor

Re : Sed résultat inattendu !

Bonsoir,

Bon voilà...

J'avoue que j'y ai passé un peu de temps (surtout pour réfléchir au "comment") (j'aime pas les échecs ... il me faut absolument trouver une solution wink)
C'est un peu à l'état de brouillon mais c'est fonctionnel.
Il y a toutefois 2 restrictions :
1. il faut que les 2 motifs soient sur des lignes distinctes.
2. il ne doit pas y avoir d' "exp1" dans la Nième occurence
ex de ko :

exp1
a
exp2
exp1
exp1
b
exp2

L'idée est la suivante :
- afficher jusqu'à trouver la première occurence de "exp1"
- puis, utiliser la mémoire principale pour conserver les lignes jusqu'à trouver la fin de la Nième occurence
- à chaque occurence "/exp1/, /exp2/ ", on ajoute un "1" dans la mémoire annexe.
- 1 fois la Nième occurence trouvée (donc N fois le chiffre 1 dans la mémoire annexe), suppression des dernières lignes de la mémoire principale jusqu'à trouver exp1 (d'où la 2nde restriction)
- afficher le restant de ligne

le code :

/exp1/ {
:deb1
N
/exp2[^\n]*$/ { 
# on indique que l'on a trouve une occurence en rajoutant un "1" dans la memoire secondaire
x
s/.*/1&/
# on verifie que l'on a pas atteint l'occurence voulue (ici = 2nde)
/1{2}/  {x; b suppr }
x
b deb2 }

b deb1
:deb2
N
/exp1[^\n]*$/ { b deb1 }
b deb2

:suppr
# tant que la dernière ligne ne contient pas exp1, alors on supprime la dernière ligne
s/\n[^\n]+$//
/exp1[^\n]*$/ { s/\n?[^\n]+$//; /^$/ b affiche; p; s/.*//; N; s/^\n//; b affiche}
b suppr
:affiche
N
b affiche
}

j'avoue qu'il n'y a pas d'interêt à faire cela avec sed... sauf l'intérêt technique wink
les 2 restrictions peuvent probablement être contournées mais c'est déjà un bon début...

mon fichier de test :

0
exp1
-1
exp2
exp1
-2
-2
exp2
exp1
-3
-3
-3
exp2
-4

A noter qu'il faut utiliser l'option -r de sed ...
exemple :

sed -rf fichier.sed fichier.dat

@+

EDIT : légère amélioration du script

Dernière modification par Totor (Le 17/01/2010, à 01:46)


-- Lucid Lynx --

Hors ligne

#23 Le 18/01/2010, à 04:15

Mpok

Re : Sed résultat inattendu !

<Note HS> : j'aurais du vous poser MA question AVANT (Totor et nesthib)... Cela m'aurait évité de passer par un prog C (pour un pbm initial équivalent) et deux mois de programmation (parce que j'ai du coup "poussé" un peu le pbm initial).</HS>

Hors ligne