BASH: rechercher/remplacer sur 2 lignes

Résolu
boyquotes Messages postés 16 Statut Membre -  
zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,


Je cherche à remplacer 2 lignes d'une template html par une autre ligne mais je n'arrive pas à prendre en compte le saut de ligne pour tourver mes 2 lignes.

exemple fichier "test":
une ligne
deux ligne
trois ligne

Je souhaite trouver les deux lignes matchant et les remplacer par OK mais ça ne marche pas:

sed 's/une ligne\ndeux ligne/OK/g' test
sed 's/une ligne\\\ndeux ligne/OK/g' test

Contrainte:
Je peux pas me servir du numéro de ligne, car suivant les fichiers de template, il peut être différent...

Par contre l'inverse fonctionne faire 2 ligne a partir d'une seule ligne rechercher:
sed 's/une ligne/OK\nOK/g' test

D'avance merci
Nicolas.

8 réponses

  1. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
     
    Bon au cas ou...

    $ cat fich.html 
    <div id="wrapper">
    	<div id="subwrapper">
    		
    		<div id="colonne_droite_ls">
    	#INCLURE "template/menu.html"
    	#INCLURE "template/signature.html"
    		</div>
    
    <div id="wrapper">
    	<div id="subwrapper">
    		
    		<div id="colonne_droite_ls">
    	#INCLURE "template/signature.html"
    		</div>
    
    $ sed '\|#INCLURE "template/menu.html"|{n;\|signature.html|d}' fich.html 
    <div id="wrapper">
    	<div id="subwrapper">
    		
    		<div id="colonne_droite_ls">
    	#INCLURE "template/menu.html"
    		</div>
    
    <div id="wrapper">
    	<div id="subwrapper">
    		
    		<div id="colonne_droite_ls">
    	#INCLURE "template/signature.html"
    		</div>
    
    $
    1
  2. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
     
    Salut,

    Il y a plusieurs façons pour faire ça via "sed", par contre il serait mieux que tu nous affiches un exemple tiré du contexte réel, sans quoi on risque de patauger un moment, surtout en raison des des balises utilisées en html qui interfèrent souvent avec la syntaxe de "sed".

    Donc merci d'afficher un exemple concret AVANT => APRÈS de ce que tu veux exactement.

    ;-))
    0
  3. Mihawk Messages postés 4753 Statut Contributeur 846
     
    Salut,
    Peut-être que je vais être à côté de la plaque, mais je sais qu'en regexp, le terme "\s" permet de signifier un espace blanc ; c'est-à-dire un espace, mais également un saut de ligne.

    0
  4. boyquotes Messages postés 16 Statut Membre 33
     
    Merci pour le \s , mais il fonctionne seulement avec les espaces blanc.

    Bon, vous l'aurez voulu, voici le script qui va remplacer les occurrences:
    #!/bin/bash
    chercher='#INCLURE "template/menu.html"\n\t#'
    echo $chercher
    chercher_echapper=$(echo $chercher | sed 's/\//\\\//g')
    echo $chercher_echapper
    
    remplacer_par='#INCLURE "template/pied.html"\n\t#INCLURE "template/pied_credit.html'
    echo $remplacer_par
    remplacer_par_echapper=$(echo $remplacer_par | sed 's/\//\\\//g')
    echo $remplacer_par_echapper
    
    sed "s/$chercher_echapper/$remplacer_par_echapper/g" connexion_directe.html


    Le fichier concerné connexion_directe.html
    #PARAM_FOND_nopageret=1
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    	#INCLURE "template/meta.html"
    
    </head>
    <body>
    <div id="top">
    				<div id="chemin">
    				<div id="navigation_ls">
    ::navigation:: :<a href="#URLSOMMAIRE">::accueil::</a> / ::identif::
    				</div>		
    				</div>
    			#INCLURE "template/entete.html"
    </div>
    	#INCLURE "template/ajout_panier.html"
    
    		
    <div id="wrapper">
    	<div id="subwrapper">
    		
    		<div id="colonne_droite_ls">
    	#INCLURE "template/menu.html"
    	#INCLURE "template/signature.html"
    		</div>
    		<div id="contenu">
    		
    		<div class="box_ls quarante_cinq mwdeux border_round">
    			<div id="connexion_ls">
    			<h2>::jsuisdejaclient::</h2>
                <form action="#VARIABLE(urlsite)/?fond=connexion_directe" method="post" name="connexion" id="connexion">
                <input type="hidden" name="action" value="connexion" />
                <p>
                <label for="email">::monemail:: #ERRCONNEX[<span class="obligatoire">::emailmdperr::</span>]</label>
                <input name="email" type="text" />
                </p>
                <p>
                <label for="motdepasse"> ::monmdp:: </label>
                <input name="motdepasse" type="password"/>
                </p>
                <div id="valider_connexion">
                <p class="derniereLigne"><button type="submit" class="large blue awesome"><span><span>::valider::</span></span></button></p>
                <a href="#VARIABLE(urlsite)/?fond=mdpoublie" class="green awesome">::mdpperdu::</a>
    				</div>	
                </form>
    			</div>
    		</div>
    		
    		<div class="box_ls quarante_cinq mwdeux border_round_haut">
    			<h2>::nvclient::</h2>
    		</div>
    		<div class="box_ls quarante_cinq  mdeux border_round_bas">
    							<THELIA_ARTICLE type="CONTENU"  id="16">
    								<p>
    								#DESCRIPTION
    								</p>
    							</THELIA_ARTICLE>
    			<div id="aide_connexion_ls">
    				<a href="#VARIABLE(urlsite)/?fond=creer_compte" class="large blue awesome">Créer un compte</a>
    			</div>
    		</div>
    			<div class="place_retour_connexion">		
    				<a class="large blue awesome fermer_affiche_ajout" href="#URLSOMMAIRE"><span><span>::retourboutique::</span></span></a>
    			</div>
    		</div>
    
    	</div>
    </div>
    
    	#INCLURE "template/bandeau_fct_bas.html"
    
    	#INCLURE "template/pied.html"
    	#INCLURE "template/pied_credit.html"
    
    <script language="JavaScript" type="text/javascript" src="template/js/wz_tooltip.js"></script>
    </body>
    </html>


    Donc les slash et caractère html, c'est normalement géré par le script que j'ai fait, d'ou le fait que je préfére travailler mon soucis de reconnaissance de saut de ligne dans le petit fichier exemple.

    Nicolas
    0
    1. Mihawk Messages postés 4753 Statut Contributeur 846
       
      Arrrrrrrrrrrrrrrrrgh !
      0
    2. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
       
      Entendons-nous bien...

      Tu veux juste remplacer :
      	<div id="subwrapper">
      		
      		<div id="colonne_droite_ls">
      	#INCLURE "template/menu.html"
      	#INCLURE "template/signature.html"
      		</div>

      Par :
      		<div id="colonne_droite_ls">
      	#INCLURE "template/pied.html"
      	#INCLURE "template/pied-credit.html"
      	#INCLURE "template/signature.html"
      		</div>
      		<div id="contenu">
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. boyquotes Messages postés 16 Statut Membre 33
     
    Non petite erreur de ma part, chercher contient en fait
    chercher" #INCLURE "template/menu.html"
    #INCLURE "template/signature.html""

    Et c'est bien là que je sais pas quoi mettre:
    chercher='#INCLURE "template/menu.html"\n\t#INCLURE "template/signature.html'
    ....

    Pour obtenir:
    	<div id="subwrapper">
    		
    		<div id="colonne_droite_ls">
    	#INCLURE "template/menu.html"
    	#INCLURE "template/signature.html"
    		</div>


    Par :
    		<div id="colonne_droite_ls">
    	#INCLURE "template/menu.html"
    		</div>
    		<div id="contenu">


    Mais je peux pas simplement enlever la ligne signature car quand il se trouve à d'autre endroit( bas de page du fichier html) et il doit y rester donc un:
    sed 's/#INCLURE"template\/signature.html"//g' *.html n'est pas possible

    Je dois remplacer les deux lignes par la ligne #INCLURE "template/menu.html" , c'est la meilleur méthode si ça peut fonctionner...

    Nicolas.
    0
    1. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
       
      Je ne comprends plus rien ;-(((

      Merci d'afficher un exemple de ton fichier AVANT => APRÈS comme je l'ai fait plus haut !
      0
  7. Mihawk Messages postés 4753 Statut Contributeur 846
     
    Et que se passe-t-il si tu remplaces le \n par un "\s+" qui gèrerait la présence de plusieurs espaces + sauts de lignes ?

    Tant qu'on ne fait pas, on ne sait pas.
    0
  8. boyquotes Messages postés 16 Statut Membre 33
     
    Merci, ce dernier sed est bon, j'avoue ne pas tous saisir, d pour delete, le n doit être le saut de ligne quand au pipe, je sais pas pourquoi( c'est un 'ou'?)...faut que je regarde ça de plus près ( https://forums.commentcamarche.net/forum/affich-37620122-sed-introduction-a-sed-part-iii )

    Sinon le s+ n'a rien donné de valable pour le saut de ligne.

    Voici le script final, qui d'ailleurs pourrait se simplifier par la simple ligne que tu a fait d'ailleurs, mais ça me permettra de le lancer pour d'autre partie en ne changeant que 2 variables:

    #!/bin/bash
    chercher0='#INCLURE "template/menu.html"'
    echo $chercher0
    chercher=$(echo $chercher0| sed 's/\//\\\//g')
    chercher_a_supprimer='signature.html'
    echo $chercher_a_supprimer
    sed -i "\|$chercher|{n;\|signature.html|d}" *.html


    Bonne journée.
    Nicolas
    0
    1. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
       
      Re-

      d pour delete,
      Oui, ça c'est bon ;-)


      le n doit être le saut de ligne
      Euh... non ;-((
      Le "n" c'est pour dire qu'on veut mettre la prochaine ligne dans le buffer (mémoire) de sed.
      Quand sed rencontre une ligne correspondant au motif recherché, il vide son buffer (en l'envoyant sur la sortie standard) et place la ligne suivant dans sa mémoire principale grace à la commande "n" (next) et fait le traitement approprié (ici on supprime avec "d" pour delette)

      quand au pipe, je sais pas pourquoi( c'est un 'ou'?)
      Non, pas du tout ;-(
      En fait si tu remarque bien le 1er pipe est précédé d'un caractère d'échappement (\) pour le protéger et ainsi dire à sed qu'on va utiliser ce caractère (le pipe) comme caractère délimiteur en lieu et place de celui par défaut, à savoir le slash (/), ceci parce que le motif recherché contient des slashs. En fait on peut utiliser le caractère qu'on veut du moment où il n'apparaît pas dans le motif.
      0
    2. boyquotes Messages postés 16 Statut Membre 33
       
      Merci zipe31, je vois que j'ai encore quelques heures à passer sur sed pour mieux comprendre ses subtilités.

      As-tu jeté un oeil à ce post : https://forum.macbidouille.com/index.php?showtopic=128499 

      Cela traite uniquement le saut de ligne, moi j'avais besoin de traiter ce qu'il y a avant et après.

      Merci à tous.
      Nicolas
      0
    3. zipe31 Messages postés 34620 Date d'inscription   Statut Contributeur Dernière intervention   6 501
       
      Merci de relire le post #9 et de s'y tenir pour une meilleure résolution des problèmes ;-))
      0