Contenu | Rechercher | Menus

Annonce

Si vous rencontrez des soucis à rester connecté sur le forum (ou si vous avez perdu votre mot de passe) déconnectez-vous et reconnectez-vous depuis cette page, en cochant la case "Me connecter automatiquement lors de mes prochaines visites".
Test de l'ISO d'Ubuntu francophone : nous avons besoin de testeurs pour la version francophone d'Ubuntu 14.04. Liens et informations ici.

Attention, une faille de sécurité dans bash a récemment été rapportée, il est recommandé de mettre à jour son système (plus de détails) *** mise à jour 12/10/2014 ***

#1 Le 18/03/2013, à 15:23

JujuLand

[Résolu] Lacunes ...

Bon, voila un problème très simple, mais que je n'arrive pas à résoudre.

Mon but est de récupérer un chaîne dans un fichier, et de remplacer une autre chaîne par cette première dans un autre fichier

Voici ce que je sais faire :

Récupération de la ligne :
cat ChangeLog|grep -m 1 'UTC-0800 Pritpal Bedi'
Résultat
2013-03-15 18:45 UTC-0800 Pritpal Bedi (bedipritpal at hotmail.com)(r189)

Remplacement de la chaîne dans le second fichier :
cat hbide.juj | awk '{ sub("VERSION", "r189"); print }'>./hbide_v.ch

Je sais faire ces deux choses, mais pas récupérer la chaine dans la première commande, et l'injecter dans la deuxième commande.

Merci de vos lumières

A+

Dernière modification par JujuLand (Le 19/03/2013, à 10:34)

Hors ligne

#2 Le 18/03/2013, à 16:09

pingouinux

Re : [Résolu] Lacunes ...

Bonjour,

Méthode 1

str=$(awk -F"(" '/UTC-0800 Pritpal Bedi/ {print substr($3,0,length($3)-1);exit}' ChangeLog)
sed "s/VERSION/$str/" hbide.juj >./hbide_v.ch

Méthode 2

sed "s/VERSION/$(awk -F"(" '/UTC-0800 Pritpal Bedi/ {print substr($3,0,length($3)-1);exit}' ChangeLog)/" hbide.juj >./hbide_v.ch

En ligne

#3 Le 18/03/2013, à 16:34

JujuLand

Re : [Résolu] Lacunes ...

Bonjour.

Je pensais bien qu'un sed ferait l'affaire. J'avais essayé avec des redirections ou des pips, mais je n'y arrivais pas.
J'aime bien la deuxième version très compacte, même si la version avec variable est plus simple à comprendre.

Un grand merci
A+

Hors ligne

#4 Le 18/03/2013, à 16:40

pingouinux

Re : [Résolu] Lacunes ...

Voici plus simple :

str=$(awk -F")" '/UTC-0800 Pritpal Bedi/ {print substr($2,2);exit}' ChangeLog)
sed "s/VERSION/$str/" hbide.juj >./hbide_v.ch

ou

sed "s/VERSION/$(awk -F")" '/UTC-0800 Pritpal Bedi/ {print substr($2,2);exit}' ChangeLog)/" hbide.juj >./hbide_v.ch

Ajouté :
On peut aussi récupérer la chaîne avec grep :

str=$(grep -Po '^.*UTC-0800 Pritpal Bedi.*\(\K[^\(]+(?=\)$)' ChangeLog)

Dernière modification par pingouinux (Le 18/03/2013, à 17:08)

En ligne

#5 Le 18/03/2013, à 17:57

JujuLand

Re : [Résolu] Lacunes ...

Je bricolais sur les syntaxes envoyées, et je me disais que je pourrais me passer d'écraser le fichier original, et que je pourrais tout aussi bien remplacer la version dans le fichier d'origine.

Dans le fichier d'origine, j'ai parfois quelque chose comme : 

define _HBMK_VCS_ID_   "r172/174M"

J'ai donc essayé de récupérer l'ancienne chaîne, pour pouvoir ensuite avec sed remplacer l'ancienne version par la nouvelle.
Mais je n'arrive à rien, car awk ne semble pas apprécier le #. Pour test, je l'ai enlevé, et il trouve bien. De plus, mais je n'ai pas fait l'essai, mais le / dans la chaîne à extraire risque bien de poser un problème.
J'avais essayé de simplement, avec un grep, de récupérer la ligne sans spécifier le #

cat hbide_v.ch|grep 'define _HBMK_VCS_ID_'

et çà fonctionne, mais je n'arrive pas à le faire bouffer par awk, avec un truc du style

old1=awk '/define _HBMK_VCS_ID_/ {print substr($3,2,length($3)-2);exit}' $(cat hbide_v.ch|grep 'define _HBMK_VCS_ID_')

mais awk veut un fichier en entrée, semble-t-il

Enfin, j'ai aussi à remplacer la version dans un autre fichier, la ligne étant de ce style :

      AAdd( txt_, "QtContribs " + " r" + "187" )

Et là aussi, j'ai des problèmes avec awk, probablement à cause des " inclus dans la chaîne, ou encore parce que ceci étant un source indenté, il y a des espaces en tête.

Bref, je patauge encore pas mal ...

A+

Dernière modification par JujuLand (Le 18/03/2013, à 18:05)

Hors ligne

#6 Le 18/03/2013, à 18:17

pingouinux

Re : [Résolu] Lacunes ...

Si tu veux remplacer 187 par autre chose dans cette ligne

      AAdd( txt_, "QtContribs " + " r" + "187" )
str=189
sed -r 's/(")[^"]+("[^"]+)$/\1'"$str"'\2/' fichier

Pour #define, peux-tu préciser ce que tu veux ?
Correction :  Pour le cas où str contiendrait des espaces

Dernière modification par pingouinux (Le 18/03/2013, à 18:22)

En ligne

#7 Le 18/03/2013, à 18:44

JujuLand

Re : [Résolu] Lacunes ...

Effectivement, je veux remplacer le 187 (qui pourra être une autre valeur).

Pour la ligne #define, c'est pareil, excepté que la chaîne serait r189 (en prenant ta valeur de str)

Donc, il me faudrait récupérer 189, et le mettre dans une variable, remplacer dans la ligne Aadd txt_, ...
Modifier la valeur de str et rajoutant r devant et ensuite remplacer r187 par la variable dans la ligne #define.

A en voir ta commande, il n'y aurait pas besoin de récupérer les anciennes valeurs à remplacer, ce qui fait qu'avec un sed, ce serait suffisant aussi pour la ligne #define ...

Ai-je bien compris ?

A+

Dernière modification par JujuLand (Le 18/03/2013, à 18:44)

Hors ligne

#8 Le 18/03/2013, à 18:55

pingouinux

Re : [Résolu] Lacunes ...

Pour le fichier contenant la ligne #define

str=189
sed -r 's=(#define[^"]+")[^"/]+(/.+)$=\1'r"$str"'\2=' fichier

En ligne

#9 Le 18/03/2013, à 19:43

JujuLand

Re : [Résolu] Lacunes ...

Bon, c'est ok, pour le #define, mais pour l'autre, çà me remplace plein de choses par 189, exemple :

   CASE 4
      cTitle := 'About Harbour'
      AAdd( txt_, "189" )
      AAdd( txt_, "" )
      AAdd( txt_, '"Harbour is the Free Open Source Software implementation' )
      AAdd( txt_, 'of a multi-platform, multi-threading, object-oriented, scriptable' )
      AAdd( txt_, 'programming language, backwards compatible with Clipper/xBase.' )
      AAdd( txt_, 'Harbour consists of a compiler and runtime libraries with multiple' )
      AAdd( txt_, 'UI and database backends, its own make system and a large' )
      AAdd( txt_, 'collection of libraries and interfaces to many popular APIs."' )
      AAdd( txt_, "" )
      AAdd( txt_, "189" )
      AAdd( txt_, "189" )
      EXIT

   END

alors qu'on a çà au départ:

   CASE 4
      cTitle := 'About Harbour'
      AAdd( txt_, "<b>About Harbour</b>" )
      AAdd( txt_, "" )
      AAdd( txt_, '"Harbour is the Free Open Source Software implementation' )
      AAdd( txt_, 'of a multi-platform, multi-threading, object-oriented, scriptable' )
      AAdd( txt_, 'programming language, backwards compatible with Clipper/xBase.' )
      AAdd( txt_, 'Harbour consists of a compiler and runtime libraries with multiple' )
      AAdd( txt_, 'UI and database backends, its own make system and a large' )
      AAdd( txt_, 'collection of libraries and interfaces to many popular APIs."' )
      AAdd( txt_, "" )
      AAdd( txt_, "Get downloads, samples, contribs and much more at:" )
      AAdd( txt_, "<a href='http://harbour-project.org/'>http://harbour-project.org/</a>" )
      EXIT

   END

A+

Hors ligne

#10 Le 18/03/2013, à 20:23

pingouinux

Re : [Résolu] Lacunes ...

Bah oui, parce que je suis parti de ton exemple

      AAdd( txt_, "QtContribs " + " r" + "187" )

et à défaut de spécifications plus précises, j'ai remplacé les chaînes non vides se trouvant entre la dernière paire de " " par le contenu de la variable str.
Il faudrait que tu indiques ce qui caractérise les lignes à traiter.

En ligne

#11 Le 18/03/2013, à 20:38

JujuLand

Re : [Résolu] Lacunes ...

Ben la ligne est
AAdd( txt_, "QtContribs " + " r" + "187" )
rien de plus qui la caractérise, et la chaine à remplacer est 187 (peut varier, évidemment)

La ligne doit donc avoir Aadd , txt_ et QtContribs

A+

Dernière modification par JujuLand (Le 18/03/2013, à 20:50)

Hors ligne

#12 Le 18/03/2013, à 21:01

pingouinux

Re : [Résolu] Lacunes ...

sed -r 's/(^\s*AAdd\( txt_, "QtContribs " \+ " r" \+ ")[^"]+(" \))$/\1'"$str"'\2/' fichier

et si on admet que le nombre d'espaces séparant les champs n'est pas fixé

sed -r 's/(^\s*AAdd\s*\(\s*txt_\s*,\s*"QtContribs "\s*\+\s*" r"\s*\+\s*")[^"]+("\s*\))$/\1'"$str"'\2/' fichier

Dernière modification par pingouinux (Le 18/03/2013, à 21:07)

En ligne

#13 Le 18/03/2013, à 21:16

JujuLand

Re : [Résolu] Lacunes ...

Bon, çà fonctionne, mais il va falloir que je me creuse le citron pour comprendre la syntaxe barbare de cette commande...

Merci
A+

Hors ligne

#14 Le 18/03/2013, à 22:24

miniSeb

Re : [Résolu] Lacunes ...

Les backslashes \ servent soit à échapper un caractère (par exemple \+ pour +) soit à faire appel à une classe interne aux expressions régulières. Pour les syntaxes complexes et compagnie, va voir du côté des regexp.

Pour expliquer (rapidement) la ligne sed de pingouinux

sed -r 's/                 # s/ pour substitute (remplacer)
### Partie un : matcher la ligne
(                                # Capture de la chaîne : ouverture de \1 
^\s*                             # la ligne commence (^) par 0, 1 ou plusieurs (*) espaces (\s)
AAdd\s*                          # suivi de la chaîne AAdd et de 0, 1 ou plusieurs (*) espaces (\s)
\(\s*txt_\s*,                    # suivi d'une parenthèse ouvrante ( \( ), de 0, 1 ou plusieurs (*) espaces (\s), de la chaîne txt_, de 0, 1 ou plusieurs (*) espaces (\s) et d'une virgule (,)
\s*"QtContribs "\s*              # suivi de 0, 1 ou plusieurs (*) espaces (\s), d'un quote ("), de la chaîne QtContribs, d'un espace, d'un quote (") et de 0, 1 ou plusieurs (*) espaces (\s)
\+\s*" r"\s*\+\s*"               # suivi d'un + (\+), de 0, 1 ou plusieurs (*) espaces (\s), d'un quote ("), d'un espace, du caractère r, d'un quote ("), de 0, 1 ou plusieurs (*) espaces (\s) d'un + (\+), de 0, 1 ou plusieurs (*) espaces (\s) et d'un quote (")
)                                # Capture de la chaîne : fermeture de \1
[^"]+                            # suivi de plusieurs caractères, excepté un quote [^"]
(                                # Capture de la chaîne : ouverture de \2
"\s*\)                           # quote (") suivi de 0, 1 ou plusieurs (*) espaces (\s) et d'une parenthèse fermante ( \) )
)                                # Capture de la chaîne : fermeture de \2
$                                # Fin de la ligne
### Partie deux : substituer la ligne
/
\1                               # Insérer ce qui est capturé dans \1
'"$str"'                         # Insérer le contenu de la variable $str (bash)
\2                               # Insérer ce qui est capturé dans \2
/' 
fichier

Voilà pour une petite éclaircie. Mais comme mentionné en début de post, il faudra creuser les expressions régulières wink

Hors ligne

#15 Le 18/03/2013, à 22:50

JujuLand

Re : [Résolu] Lacunes ...

Décidément, je merde.

Si le fichier contenant Aadd est bien modifié, celui contenant le #define ne l'est pas.

Il me semblait pourtant que ça avait fonctionné ...

Voici les commandes que j'avaient mis dans mon shell:

export newstr=$(awk -F")" '/UTC-0800 Pritpal Bedi/ {print substr($2,3);exit}' ChangeLog)
sed -r 's=(#define[^"]+")[^"/]+(/.+)$=\1'r"$newstr"'\2=' hbide/hbide_v.svn > hbide/hbide_v.ch
sed -r 's/(^\s*AAdd\( txt_, "QtContribs " \+ " r" \+ ")[^"]+(" \))$/\1'"$newstr"'\2/' hbdbu/dbu.svn >hbdbu/dbu.prg

Comme le deuxième sed fonctionnait, j'ai essayé une autre syntaxe pour le premier, un peu dans le style du deuxième, mais çà ne donne modifie rien.
Voici ce que j'ai essayé :

sed -r 's/(^\#define _HBMK_VCS_ID_   )[^"]+(" \))$/\1'r"$newstr"'\2/' hbide/hbide_v.svn > hbide/hbide_v.ch

De plus, la syntaxe de la chaine à remplacer est du style r17_ ou 178:179M
Je ne sais pas si ce : peut poser un problème

A+

Dernière modification par JujuLand (Le 18/03/2013, à 22:56)

Hors ligne

#16 Le 19/03/2013, à 04:29

pingouinux

Re : [Résolu] Lacunes ...

Jujuland   #15 a écrit :

la syntaxe de la chaine à remplacer est du style r17_

Est-ce le caractère _ (souligné), ou un caractère quelconque ?

Je ne sais pas si ce : peut poser un problème

Bien sûr que oui, on ne peut pas deviner…:)
Pour traiter le :

sed -r 's=(#define[^"]+")[^"/:]+([/:].+)$=\1'r"$newstr"'\2=' hbide/hbide_v.svn > hbide/hbide_v.ch

En ligne

#17 Le 19/03/2013, à 08:36

JujuLand

Re : [Résolu] Lacunes ...

Oups !!! Un shift manqué, et j'ai écrit R17_ au lieu de r178

La syntaxe précédente ne fonctionne pas.

Pour être plus précis, voici le contenu du fichier contenant la ligne à problème:

/* Automatically generated by hbmk2. Do not edit. */
#define _HBMK_VCS_TYPE_ "svn"
#define _HBMK_VCS_ID_   "r186"

ou encore

/* Automatically generated by hbmk2. Do not edit. */
#define _HBMK_VCS_TYPE_ "svn"
#define _HBMK_VCS_ID_   "185:186M"

PS: A me relire après premier renvoi, je ne suis plus du tout sûr que le r soit présent.
Celui que je recharge en ce moment du serveur est dans la deuxième forme.

A+

Dernière modification par JujuLand (Le 19/03/2013, à 08:39)

Hors ligne

#18 Le 19/03/2013, à 09:32

pingouinux

Re : [Résolu] Lacunes ...

Essaye avec ceci :

sed -r 's=(#define[^"]+")r?[[:digit:]]+(.*")$=\1'r"$newstr"'\2=' fichier

Voici un test :

Fichier de départ
#define _HBMK_VCS_ID_   "r172/174M"
#define _HBMK_VCS_ID_   "172/174M"
#define _HBMK_VCS_TYPE_ "svn"
#define _HBMK_VCS_ID_   "r186"
#define _HBMK_VCS_ID_   "186"
#define _HBMK_VCS_ID_   "185:186M"

Commande du #16
#define _HBMK_VCS_ID_   "r189/174M"
#define _HBMK_VCS_ID_   "r189/174M"
#define _HBMK_VCS_TYPE_ "svn"
#define _HBMK_VCS_ID_   "r186"
#define _HBMK_VCS_ID_   "186"
#define _HBMK_VCS_ID_   "r189:186M"

Commande ci-dessus
#define _HBMK_VCS_ID_   "r189/174M"
#define _HBMK_VCS_ID_   "r189/174M"
#define _HBMK_VCS_TYPE_ "svn"
#define _HBMK_VCS_ID_   "r189"
#define _HBMK_VCS_ID_   "r189"
#define _HBMK_VCS_ID_   "r189:186M"

En ligne

#19 Le 19/03/2013, à 09:58

JujuLand

Re : [Résolu] Lacunes ...

Hum, y'a du mieux, mais ça ne supprime pas l'ancienne valeur:

/* Automatically generated by hbmk2. Do not edit. */
#define _HBMK_VCS_TYPE_ "svn"
#define _HBMK_VCS_ID_   "r189:186M"

il faudrait peut-être simplement rajouter une commance de suppression des caractères entre : et "
S'il n'y sont pas, il ne ferait donc rien de plus, non ?

A+
A+

Hors ligne

#20 Le 19/03/2013, à 10:04

pingouinux

Re : [Résolu] Lacunes ...

Hum, y'a du mieux, mais ça ne supprime pas l'ancienne valeur:

Je ne comprends. Il faudrait que tu donnes la ligne initiale, et celle que tu veux obtenir.

Ajouté : Montre le résultat que tu veux avec mon exemple du #18

Dernière modification par pingouinux (Le 19/03/2013, à 10:10)

En ligne

#21 Le 19/03/2013, à 10:22

JujuLand

Re : [Résolu] Lacunes ...

Ligne initiale :

#define _HBMK_VCS_ID_   "185:186M"

ou

#define _HBMK_VCS_ID_   "187"

Ligne finale :

#define _HBMK_VCS_ID_   "r189"

Je ne suis pas sûr du r (ligne finale), mais ce n'est pas un problème, car je sais ou l'enlever

Voici donc ce que j'attends, que ce soit la ligne initiale 1 ou 2

/* Automatically generated by hbmk2. Do not edit. */
#define _HBMK_VCS_TYPE_ "svn"
#define _HBMK_VCS_ID_   "r189"

A+

Dernière modification par JujuLand (Le 19/03/2013, à 10:28)

Hors ligne

#22 Le 19/03/2013, à 10:29

pingouinux

Re : [Résolu] Lacunes ...

Avec cette commande

sed -r 's=(#define[^"]+")r?[[:digit:]]+[^"/]*(.*")$=\1'r"$newstr"'\2=' fichier

tu obtiens ce résultat sur mon exemple du #18

#define _HBMK_VCS_ID_   "r189/174M"
#define _HBMK_VCS_ID_   "r189/174M"
#define _HBMK_VCS_TYPE_ "svn"
#define _HBMK_VCS_ID_   "r189"
#define _HBMK_VCS_ID_   "r189"
#define _HBMK_VCS_ID_   "r189"

En ligne

#23 Le 19/03/2013, à 10:33

JujuLand

Re : [Résolu] Lacunes ...

Oui, là ça fonctionne

Je vais décortiquer la ligne pour essayer de comprendre
Merci
A+

Hors ligne

#24 Le 20/03/2013, à 12:57

pingouinux

Re : [Résolu] Lacunes ...

Voici quelques explications sur la commande :

sed -r 's=(#define[^"]+")r?[[:digit:]]+[^"/]*(.*")$=\1'r"$newstr"'\2=' fichier

's=(champ1)champ2(champ3)=\1'r"$newstr"'\2='

  1. champ2 contenant un /, la structure habituelle s/ancien_texte/nouveau_texte/ est remplacée
    par s=ancien_texte=nouveau_texte= (n'importe quel caractère non inclus dans un des textes peut servir de délimiteur)

  2. Les champs contenant des ", la séquence 's=…=…=' est délimitée par des ' ', mais il faut que $newstr puisse être interprétée, d'où la complication :

    's=(#define[^"]+")r?[[:digit:]]+[^"/]*(.*")$=\1'          r"$newstr"          '\2='
    • champ1
      #define[^"]+"      => #define, suivi d'un ou plusieurs caractères différents de ", suivis de "

    • champ2
      r?[[:digit:]]+[^"/]* => 0 ou 1 r, suivi d'un ou plusieurs chiffres, suivis de 0, 1 ou plusieurs caractères différents de " et de /

    • champ3
      .*"                          => 0, 1 ou plusieurs caractères quelconques, suivis de "

En ligne

#25 Le 20/03/2013, à 13:28

JujuLand

Re : [Résolu] Lacunes ...

Merci pour les explications.
Je pense que c'est largement au dessus mon niveau, et je vais maintenant bien relire tes explications.

Cà me permettra d'être moins c... devant çà, même si je doute être capable de refaire çà, et de passer ma retraite sans me creuser le choux plus que de raison ...

Merci encore
A+

Hors ligne

Haut de page ↑