SED de Linux à Unix

Résolu
Bonjour,

voilà la situation :

la commande suivante ( qui fonctionne très bien sous Linux Ubuntu ) se trouve dans un fichier perl.
elle permet d'insérer dans un fichier une variable à la ligne 13 ...

system "sed i\ '13i$variable' ../dossier/fichier.xsl";

cette même commande ne fonctionne pas sous Unis, HPUNIX pour être précis ... et malgré quelques commandes testées, une petite étude du man je ne trouve pas ... une idée ??

MERCI !! :D
Configuration: Linux
Firefox 2.0.0.11

22 réponses

Résumé de la discussion

Le fil examine la difficulté portable d’insérer une variable à la ligne 13 via sed en mode in-place, fonctionnant sous Linux mais échouant sur HP-UX en raison de la non-portabilité de l’option -i. Plusieurs réponses expliquent que -i n’est pas universel et proposent des solutions alternatives avec Perl, notamment des enchaînements -pi ou -e pour insérer du contenu à une ligne précise. Des extraits montrent comment écrire en Perl une chaîne $var et insérer à la 3e ligne ou modifier le fichier en place, avec variantes utilisant -i.orig et des constructions s/^/$var\n/ si $.==3. En pratique, la portabilité peut être assurée par Perl, évitant les soucis HP-UX; tester les scripts sur l’environnement cible avant déploiement reste toutefois recommandé et prudent.

Bobot (l’IA à votre service)
  1. Désolé de répondre si tard ...

    j'ai utilisé cette solution sous HPUX et ca fonctionne tres bien :

    #!/usr/bin/perl -i.orig
    use strict;use warnings;

    @ARGV = qw{../trash/clusterwares.xsl};
    my $ok=q{<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Instances</b></h3>};
    #
    while(<>){
    s/^/$ok\n/ if $.==3;
    print;
    }
    __END__


    Merci encore pour votre aide précieuse et pour votre patience !!!
    0
    1. Merci !!! :D
      c'est exactement ce qu'il me fallait !! je le test au boulot mercredi. là je l'ai testé chez moi mais sous linux ....
      ca devrait passer aussi sur le serveur mais je me méfie avec HPUX ...

      ;)

      merci beaucoup en tout cas !
      0
      1. Modérateur
        Salut,

        voilà
        #!/usr/bin/perl -i.orig
        use strict;use warnings;
        
        @ARGV = qw{../trash/clusterwares.xsl};
        my $ok=q{<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Instances</b></h3>};
        #
        while(<>){
                s/^/$ok\n/ if $.==3;
                print;
        }
        __END__
        
        -i.orig passé en 1ère ligne (QUI N'EST PAS UN COMMENTAIRE même si elle commence avec #)
        #! s'appele shebang
        Nous pouvons passer des options comme on le fait en ligne de commande

        Par exemple au lieu d'écrire use warnings on peut écire
        #!/usr/bin/perl -w

        si ça te semble bizarre tu peux utiliser la variable $^I ($INPLACE_EDIT avec le module English) qui fait la même chose
        #!/usr/bin/perl
        use strict;use warnings;
        
        @ARGV = qw{../trash/clusterwares.xsl};
        $^I = ".orig";
        
        my $ok=q{<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Instances</b></h3>};
        #
        while(<>){
                s/^/$ok\n/ if $.==3;
                print;
        }
        __END__


        0
        1. oui, ne lancer que "script.pl" et que le programme perl insert diretement la ligne dans le fichier voulu ...

          en gros comme le dernier code que tu m'a donné, sauf que le nom du fichier source destination soit dans le code.
          là le dernier exemple on print le résultat mais on ne l'enregistre pas dans le fichier .. et je ne trouve pas comment faire ..

          le truc c'est de faire

          -----------------------------------------------------------------------

          #!/usr/bin/perl
          use strict;

          # déclaration des variables
          my $ok=q{<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Instances</b></h3>};

          insérer la ligne "..blabla $ok " à la ligne 13 par exemple dans le fichier ../visuel/clusterwares.xsl

          ------------------------------------------------------------------------

          et n'avoir à lancer que perl script.pl

          c'est ce que j'arrivais à faire avant sous linux ... :)

          merci à toi
          0
          1. Modérateur
            pour ne lancer que script.pl, sans arguments ?
            oui, c'est possible
            je vais regarder un peu plutard

            je t'expliquerai aussi -i.orig
            0
            1. salut ! oui ne t'inquiete pas j'avais vu. petite faute de frappe sur le warning aussi ;) comme ca au moins ca me fait réfléchir et pas juste faire des copier coller. :)

              par contre justement ... peut on mettre le fichier source et destination directement dans le code pour ne lancer que script.pl, sans arguments ?

              je ne comprend pas pourquoi le -i.orig est dans la premiere ligne en commentaire .. :$

              en tout cas c'est cool de t'occuper des petits débutants comme moi :@)
              0
              1. Modérateur
                j'ai oublié un apostrophe et my
                #!/usr/bin/perl -i.orig
                use strict;use warnigns;
                
                my $ok=q{<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Instances</b></h3>}; 
                
                while(<>){
                  s/^/$ok\n/ if $.==3;
                  print;
                }
                __END__
                0
                1. Modérateur
                  ce n'est pas avec système que tu dois faire

                  tu peux le faire directement avec perl en utiliseant l'option -i dans
                  #!/usr/bin/perl -i.orig
                  use strict;use warnigns;
                  
                  $ok=q{<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Instances</b></h3>}; 
                  
                  while(<>){
                    s/^/$ok\n/ if $.==3';
                    print;
                  }
                  __END__
                  et tu lances le script avec la commande
                  perl script.pl  ../visuel/clusterwares.xsl
                  --

                  lami20j
                  0
                  1. a ok, je ne connaissais pas, très bien, ca marche nickel !! :D

                    j'ai aussi trouvé comment exécutée la commande depuis un fichier perl avec "system"... un peu différent de d'habitude, mais c'eest ok :

                    system q{perl -pi.orig -e '$var=q{<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Filesystem locaux5</b></h3>};s/^/$var\n/ if $.==3' ../visuel/clusterwares.xsl;};

                    on y est presque !!

                    il me reste qu'à détacher le contenu de la variable .. j'ai testé ca sans succès ... je continue à chercher ...

                    $var=(q{<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Filesystem locaux5</b></h3>});
                    system q{perl -pi.orig -e 's/^/$ok\n/ if $.==3' ../visuel/clusterwares.xsl;};


                    merci pour ton aide !!
                    0
                    1. Modérateur
                      mais je ne sais pas comment le formater pour qu'elle soit dans le fichier perl ping.pl par exemple.

                      dans le script tu peux utiliser l'opérateur q{} pour eviter les multiples guillemets ;-)
                      $bad=q{<h3><b><IMG src="puce_rouge.gif" align="absmiddle"></IMG> Instances</b></h3>}; 
                      --

                      lami20j
                      0
                      1. Merci pour le tuyau pour écrire le résultat dans un fichier.

                        C'est vrai que ce n'est pas facile d'expliquer comme ca ..

                        Il faut imaginer cela par modules.

                        Ping - Etat des disques - Listener - Instances Chacun des modules est un fichier perl qui lance des commandes unix, et qui EN FONCTION du résultat écrivent dans le fichier xsl.

                        au début de chaque fichier perl je déclare des variables ( quasiement les même dans chaque module ) pour, selon le résultat de la requête afficher un puce rouge ou une puce verte :

                        # Déclaration variables puces colorées
                        $bad=('<h3><b><IMG src="puce_rouge.gif" align="absmiddle"></IMG> Instances</b></h3>');
                        $ok=('<h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Instances</b></h3>');


                        dans l'exemple si dessus c'est pour le programme perl de l'instance ( en gras ), mais appart "instance" le reste est pareil.

                        Ensuite OUI, les numero de ligne pour les insertions est connu et toujours le meme et peut donc être ecrit en dur.

                        En fait je part du fichier xsl "vide" c'est à dire sans les lignes puce rouge - puce verte, et au fur et à mesure de l'exécution de mes programmes perl ca implemente ce fichier .

                        Voilà son état d'origine :

                        1<?xml version="1.0" encoding="ISO-8859-1"?>
                        2<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
                        3<xsl:template match="/">
                        4<html>
                        5<head>
                        6<title>Etat du cluster Oracle</title>
                        7</head>
                        8<body>
                        9<center><IMG src="logo.jpg"></IMG></center>
                        10<h1><center>Etat du cluster Oracle</center></h1>
                        11<h3><b>Date</b></h3>
                        12<p><xsl:value-of select="ini/date" /></p><TABLE border='0' width='160%' height='150'><TR><td>
                        13<pre><xsl:value-of select="ini/diag_materiel/ping" /></pre>
                        14<pre><xsl:value-of select="ini/diag_materiel/filesystem_locaux_5" /></pre>
                        15<pre><xsl:value-of select="ini/diag_materiel/filesystem_locaux_6" /></pre></td><td>
                        16<pre><xsl:value-of select="ini/diag_materiel/ssh_nfs" /></pre>
                        17<pre><xsl:value-of select="ini/diag_materiel/instances" /></pre>
                        18<pre><xsl:value-of select="ini/diag_materiel/listener" /></pre></td></TR></TABLE>
                        19</body>
                        20</html>
                        21</xsl:template>
                        22</xsl:stylesheet>


                        chacun des programmes perl va écrire sa ligne dans le fichier, soit pour faire apparaitre puce verte, soit puce rouge ...

                        par exemple le module qui test le ping ecrira toujours une de ces 2 variable à la ligne 13.

                        voici le code des insertion que j'avais sous linux et qui fonctionnaient ;

                        system "sed -i '13i$ok' ../visuel/clusterwares.xsl";
                        => j'ecrivais le contenu de la variable $ok ( puce verte ) à la ligne 13..

                        j'avais la meme commande dans les autres modules ...seul le numero de ligne change 21 par exemple ...
                        system "sed -i '21i$ok' ../visuel/clusterwares.xsl";

                        il me faudrait donc seulement "convertir" cette commande
                        system "sed -i '13i$ok' ../visuel/clusterwares.xsl"; qui marchait sous linux en UNIX ...

                        pas forcement avec sed.

                        Ton exemple de ce matin me va bien, il insert bien le texte, par contre je ne trouve pas la syntaxe pour mettre la commande das fichier perl ..

                        là dans le shell elle fonctionne :

                        perl -pi.orig -e '$var="<h3><b><IMG src='"'puce_verte.gif'"' align='"'absmiddle'"'></IMG> Filesystem locaux5</b></h3>";s/^/$var\n/ if $.==3' ../visuel/clusterwares.xsl

                        dans un fichier toto.sh aussi, mais je ne sais pas comment le formater pour qu'elle soit dans le fichier perl ping.pl par exemple.

                        Voilà, j'espere avoir répondu à tes question. c'est tres sympa en tout cas d'avoir le courage de em lire et d'essayer de me répondre :)

                        ps :

                        du fait de ma variable "compliquée" avec des "<" et des guillemets, j'ai été obligé d'improviser comme tu as pu le voir avec de multiples guillemets autour de puce_verte par exemple , mais ca marche, c'est bon ;)

                        $var="<h3><b><IMG src='"'puce_verte.gif'"' align='"'absmiddle'"'></IMG> Filesystem locaux C7ORA5</b></h3>";
                        0
                        1. Modérateur
                          j'espere avoir répondu a ta question ...

                          en fait, ce n'est pas très clair
                          l'emplacement (numéro de ligne) - tu le connais d'avance ou c'est variable?!
                          ce que tu veux insérer je vois que c'est variable.

                          bref, il faut trouver l'emplacement et la ligne qu'il faut insèrer.

                          pour l'instant pour moi ce n'est pas clair

                          donc si tu arrives à me faire comprendre ce que tu vex faire, je pourrai te donner la solution ;-)
                          0
                          1. Modérateur
                            Salut,

                            je vais regarde de plus près ce soir ;-)

                            dans le print ... j'ai "bêtement" fait un ">"

                            perl -ne '$var='noir';s/^/$var\n/ if $.==3;print' > phoenix1984

                            mais ca a tout effacé dans le fichier ...


                            je suis d'accord toi avec bêtement ;-))

                            il fallait faire
                            perl -ne '$var="noir";s/^/$var\n/ if $.==3;print'  phoenix1984 > autre_fichier
                            ou
                            perl -pi.orig -e '$var="noir";s/^/$var\n/ if $.==3'  phoenix1984 
                            --

                            lami20j
                            0
                            1. salut ! premiererement merci pour ta réponse !

                              pour ce qui est de la condition d'écriture, il n'y en a pas en faite .. je vais essayer d'expliquer clairement. je bosse sur une supervision de cluster oracle en perl.
                              différents points sont "surveillés" ( accèssibilité, nombre de listener de la base, état des filesystem, etc ... ). le résultat apparait sur une page html générée d'apres un .xml et .xsl ...
                              mon programme perl lance des commandes unix pour récupérer les infos sur les serveurs.

                              dans notre cas précis : la condition se fait en amont :

                              si le serveur ne répond pas il faut mettre un voyant rouge dans le fichier xsl.
                              si le serveur répond il faut mettre un voyant vert dans le fichier xsl.

                              d'où mon besoin d'insertion de telle ou telle variable dans le fichier xsl ...

                              le mécanisme je l'ai bien compris, et tout fonctionne tres bien depuis une machine linux ... mais lors de la mise en test avant production le tout tourne sous unix ( ca sera le cas à terme ) et là j'ai eu le problème d'insertion ....

                              j'espere avoir répondu a ta question ...

                              Donc, pour finir, je n'ai meme pas besoin de vérifier sur la ligne est vide ou non .. dans tous les cas je vais insérer une ligne ... c'est juste la variable qui changeras

                              ci dessous un extrait de mon xsl

                              <?xml version="1.0" encoding="ISO-8859-1"?>
                              <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
                              <xsl:template match="/">
                              <html>
                              <head>
                              <title>Etat du cluster Oracle</title>
                              </head>
                              <body>
                              <center><IMG src="logo.jpg"></IMG></center>
                              <h1><center>Etat du cluster Oracle</center></h1>
                              <h3><b>Date</b></h3>
                              <p><xsl:value-of select="ini/date" /></p><TABLE border='0' width='160%' height='150'><TR><td>
                              <h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Disponibilite</b></h3>
                              <pre><xsl:value-of select="ini/diag_materiel/ping" /></pre>
                              <h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Filesystem locaux 5</b></h3>
                              <pre><xsl:value-of select="ini/diag_materiel/filesystem_locaux_5" /></pre>
                              <h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Filesystem locaux 6</b></h3>
                              <pre><xsl:value-of select="ini/diag_materiel/filesystem_locaux_6" /></pre></td><td>
                              <h3><b><IMG src="puce_orangee.gif" align="absmiddle"></IMG> Filesystem NFS</b></h3>
                              <pre><xsl:value-of select="ini/diag_materiel/ssh_nfs" /></pre>
                              <h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Instances</b></h3>
                              <pre><xsl:value-of select="ini/diag_materiel/instances" /></pre>
                              <h3><b><IMG src="puce_verte.gif" align="absmiddle"></IMG> Listener</b></h3>
                              <pre><xsl:value-of select="ini/diag_materiel/listener" /></pre></td></TR></TABLE>
                              </body>
                              </html>
                              </xsl:template>
                              </xsl:stylesheet>

                              en gras : les lignes que je dois insérer suite à mes tests ...

                              en perl sous linux voilà ce que j'utilisais :

                              system "sed -i '13i$ok' ../visuel/clusterwares.xsl"; # insertion à la ligne 13 du fichier .xsl de $ok

                              ton code au dessus n'implemente pas le fichier destination par contre ... :s la modif n'apparait que dans le print ... j'ai "bêtement" fait un ">"

                              perl -ne '$var='noir';s/^/$var\n/ if $.==3;print' > phoenix1984

                              mais ca a tout effacé dans le fichier ...

                              merci de ton aide et/ou de celle des autres ;)
                              0
                              1. Modérateur
                                ou
                                lami20j@debserv:~/trash$ cat phoenix1984
                                le
                                chat
                                dort
                                près
                                du
                                feu
                                lami20j@debserv:~/trash$ perl -ne '$var='noir';s/^/$var\n/ if $.==3;print' phoenix1984
                                le
                                chat
                                noir
                                dort
                                près
                                du
                                feu
                                lami20j@debserv:~/trash$
                                
                                0
                                1. Modérateur
                                  Salut à vous,

                                  c'est ça que tu veux faire?
                                  lami20j@debserv:~/trash$ cat phoenix1984
                                  le
                                  chat
                                  dort
                                  près
                                  du
                                  feu
                                  lami20j@debserv:~/trash$ perl -ne '$var='noir';s/^/$var\n/ if 3..3;print' phoenix1984
                                  le
                                  chat
                                  noir
                                  dort
                                  près
                                  du
                                  feu
                                  lami20j@debserv:~/trash$
                                  Il faut adapter. Il sera mieux de savoir sur quel fichier tu travailles, ainsi que la condition d'insertion, peut être qu'on sera pas obliger d'utiliser le nombre de ligne.
                                  0
                                  1. ok, merci en tout cas pour tes réponses, c'est gentil !

                                    j'ai envoyé un MP à lami20j au cas où il ne tombe pas sur le poste :)
                                    0
                                    1. Modérateur
                                      Je pense qu'on va attendre le verdict de lami20j pour ce qui concerne le perl...

                                      Désolé ;-(
                                      0
                                      1. Modérateur
                                        Re-
                                        $ cat plop
                                        le
                                        chat
                                        dort
                                        près
                                        du
                                        feu
                                        
                                        $ var="noir";fich="$(cat plop)";echo "$fich" | sed "3 i $var" > plop
                                        
                                        $ cat plop
                                        le
                                        chat
                                        noir
                                        dort
                                        près
                                        du
                                        feu
                                        ;-))
                                        0
                                        1. sniff!! :'(

                                          merci pour ta réponse, mais voilà ce que j'obtiens :

                                          " sed : Function 3 i cannot be parsed" ...

                                          ma version d'unix : HPUX 11i version 2

                                          dur dur ... dire que ca marche tres bien en linux ... je viens de la tester sous ma ubuntu => nikel .. et pas sous hpux ...
                                          0
                                        2. Modérateur
                                          @phoenix1984;-((

                                          Quelle version de "sed" ?
                                          0
                                        3. @jipicy$Revision: B11.23.0409LR

                                          donc apparament c'est 4.09 la version de sed et B11.23 celle d'HPUX ...

                                          :)
                                          0
                                      2. merci à toi c'est bien sympa je regarde ca en attendant oui :)
                                        0
                                        • 1
                                        • 2