Résolu le 20-09-24 Problème avec la commande sed

Postez ici toutes vos demandes d’assistance.
Répondre
Avatar du membre
damad
Messages : 99
Enregistré le : jeu. 17 août 2023 14:06
Localisation : Neuchâtel, Suisse

Problème avec la commande sed

Message par damad »

Bonjour à toutes et à tous !! :D

J'essaie de faire un script pour automatiser la personnalisation de mon bureau xfce4 pour me simplifier la vie lors de nombreux tests avec des machines virtuelles. Avec la commande xfconf-query, j'ai presque tout paramétré. Mais certaines choses ne semblent pas possibles.

J'ai donc décidé d'utiliser la commande sed directement sur le fichier XML correspondant pour ajouter des lignes après une ligne selon un motif mais rien ne marche. J'ai regardé plein de tutos sur sed avec des exemples pratiques, sans succès. :cry:

Concrètement, je veux insérer ces 6 lignes :

Code : Tout sélectionner

          <property name="rgba1" type="array"> 
            <value type="double" value="0.000000"/> 
            <value type="double" value="0.000000"/> 
            <value type="double" value="0.000000"/> 
            <value type="double" value="1.000000"/>
          </property>
après cette ligne :

Code : Tout sélectionner

          <property name="last-image" type="string" value="/home/ced/Images/Wallpapers/Black.jpg"/>
dans le fichier /$HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml dont voici un extrait :

Code : Tout sélectionner

....
      <property name="monitorLVDS-1" type="empty"> 
        <property name="workspace0" type="empty"> 
          <property name="color-style" type="int" value="0"/> 
          <property name="image-style" type="int" value="0"/> 
          <property name="last-image" type="string" value="/home/ced/Images/Wallpapers/Black.jpg"/> 
        </property>
....
ce qui devrait donner ça au final :

Code : Tout sélectionner

....
      <property name="monitorLVDS-1" type="empty"> 
        <property name="workspace0" type="empty"> 
          <property name="color-style" type="int" value="0"/> 
          <property name="image-style" type="int" value="0"/> 
          <property name="last-image" type="string" value="/home/ced/Images/Wallpapers/Black.jpg"/> 
          <property name="rgba1" type="array"> 
            <value type="double" value="0.000000"/> 
            <value type="double" value="0.000000"/> 
            <value type="double" value="0.000000"/> 
            <value type="double" value="1.000000"/> 
          </property>
        </property>
....
A noter l'importance des espaces au début des lignes et les caractères spéciaux utilisés.

Je m'en remets donc à vous, car je sèche depuis 2 jours et ça commence à m'***censuré*** sérieusement... :evil:

Merci d'avance pour vos réponses !!
Pc 1 : Portable CLEVO W150HRM | Linux Mint 21.1 Vera | Cinnamon 5.6.8 | 5.15.0-122-generic x86_64 | Quad core Intel Core i7-2720QM | 8 Go | 1: Intel 2nd Generation Core Processor Family Integrated Graphics 2: NVIDIA GF106M [GeForce GT 555M]

Pc 2 : Portable Acer Predator PH18-72 v: V1.06 | Linux Mint 22 Wilma | Xfce v: 4.18.1 | 6.8.0-45-generic arch: x86_64 bits | Intel Core i9-14900HX | 32 Go | 1: Intel Raptor Lake-S UHD Graphics 2: NVIDIA AD104M [GeForce RTX 4080 Max-Q / Mobile]

Avatar du membre
Armaggion
Messages : 172
Enregistré le : jeu. 22 août 2024 16:48

Re: Problème avec la commande sed

Message par Armaggion »

Bonjour damad,

De base, sed n'est pas la commande la plus adaptée à la modification d'un fichier XML. Il existe des outils dédiés qui savent gérer la structure XML plus spécifiquement. Ceci dit ça reste faisable bien entendu.

Un peu de setup d'abord : je me crée un dossier de test, j'y crée un fichier test.xml dans lequel je mets le contenu que tu dis.

Code : Tout sélectionner

armaggion@fractal:~$ mkdir test
armaggion@fractal:~$ cd test
armaggion@fractal:~/test$ touch file.xml
armaggion@fractal:~/test$ xed file.xml&
[1] 5438
armaggion@fractal:~/test$ cat file.xml
....
      <property name="monitorLVDS-1" type="empty"> 
        <property name="workspace0" type="empty"> 
          <property name="color-style" type="int" value="0"/> 
          <property name="image-style" type="int" value="0"/> 
          <property name="last-image" type="string" value="/home/ced/Images/Wallpapers/Black.jpg"/> 
          </property>
....
Plusieurs petites choses à savoir qui ont pu t'égarer :
  • La commande sed fonctionne par remplacement. Tu ne peux pas juste insérer du texte quelque part sans permettre à sed d'identifier une correspondance et à partir de quoi il va pouvoir procéder à une substitution. L'idée ici sera donc de remplacer le contenu entier de ta ligne 5 par elle-même déjà (car on veut quand même la conserver, pas juste la remplacer) plus 4 lignes supplémentaires. Cependant...
  • La commande sed fonctionne par ligne. Or, ici, toi tu veux insérer des lignes supplémentaires. Si tu tentes d'insérer une ligne supplémentaire avec un [Enter] dans ta commande, ce [Enter] est immédiatement interprété comme la fin de la commande et l'exécution va se lancer prématurément. Les retours à la ligne sont donc à intégrer directement dans la chaîne de substitition, ce qui se fait avec un "\n".
  • Enfin dernière subtilité : le caractère "/" est recherché par la commande sed pour lui permet de bien comprendre ce qu'on lui veut :
    1. L'opération à effectuer : ici "s" pour "substitution"
    2. la chaîne de caractères à rechercher pour identifier la ligne sur laquelle on va travailler, et enfin
    3. la chaîne de caractères par laquelle on remplace ce qui a été mis en correspondance.
    Il est donc critique que sed n'interpète pas les "/" dans ton chemin de fichier (ou de fin de balise XML) comme ses propres séparateurs. Pour distinguer entre les "/" de ton chemin et les "/" de sed, on va les "échapper" en les protégeant par un "\" juste avant. De cette façon, on va dire que sed ne les "voit" pas.
Ce qui donne :

Code : Tout sélectionner

armaggion@fractal:~/test$ sed 's/          <property name="last-image" type="string" value="\/home\/ced\/Images\/Wallpapers\/Black.jpg"\/>/          <property name="last-image" type="string" value="\/home\/ced\/Images\/Wallpapers\/Black.jpg"\/>\n          <property name="rgba1" type="array">\n            <value type="double" value="0.000000"\/>\n            <value type="double" value="0.000000"\/>\n            <value type="double" value="0.000000"\/>\n            <value type="double" value="1.000000"\/>/' file.xml
....
      <property name="monitorLVDS-1" type="empty"> 
        <property name="workspace0" type="empty"> 
          <property name="color-style" type="int" value="0"/> 
          <property name="image-style" type="int" value="0"/> 
          <property name="last-image" type="string" value="/home/ced/Images/Wallpapers/Black.jpg"/>
          <property name="rgba1" type="array">
            <value type="double" value="0.000000"/>
            <value type="double" value="0.000000"/>
            <value type="double" value="0.000000"/>
            <value type="double" value="1.000000"/> 
          </property>
....
armaggion@fractal:~/test$ 
Ca te va ?
Pc : Desktop | Linux Mint 22 Wilma | Cinnamon | 6.8.0-41-generic | Intel Core i5-6600K | 16GB | Intel HD Graphics 530 / i915 + NVIDIA GA104 [GeForce RTX 3070] / 550.107.02

Avatar du membre
damad
Messages : 99
Enregistré le : jeu. 17 août 2023 14:06
Localisation : Neuchâtel, Suisse

Re: Problème avec la commande sed

Message par damad »

Ouuuaaah !! Ça c'est une réponse rapide on ne peut plus claire et détaillée, merci beaucoup d'avoir pris le temps de tester !! :B
Et ça marche !! :D

J'avais essayé cette technique de remplacer la ligne recherchée par la ligne recherchée + les lignes supplémentaires mais je n'avais pas intégrer la nécessité d'utiliser les « \ ». Et effectivement, je tournais en rond. :(

Cela dit, oui, on peut ajouter des lignes, avec sed, avant ou après une ligne correspondant à un motif avec les options « i » ou « a ». Mais ça ne marchait pas non plus à cause de l'absence des « \ »...

Voilà donc ce que ça donne avec l'option « a »  et en passant par une variable :

Code : Tout sélectionner

b='\          <property name="rgba1" type="array">\n            <value type="double" value="0"/>\n            <value type="double" value="0"/>\n            <value type="double" value="0"/>\n            <value type="double" value="1"/>\n          </property>'

sed -i "/Black/a $b" /$HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml
La variable « $b » contient les lignes à ajouter avec les « \ » requis. Je recherche donc la ligne contenant « Black » et j'ajoute la variable « $b » après cette ligne avec l'option « a ». Et ça marche aussi !! ;)

En te remerciant encore pour ton aide précieuse, je passe le sujet en « résolu ». :D
Pc 1 : Portable CLEVO W150HRM | Linux Mint 21.1 Vera | Cinnamon 5.6.8 | 5.15.0-122-generic x86_64 | Quad core Intel Core i7-2720QM | 8 Go | 1: Intel 2nd Generation Core Processor Family Integrated Graphics 2: NVIDIA GF106M [GeForce GT 555M]

Pc 2 : Portable Acer Predator PH18-72 v: V1.06 | Linux Mint 22 Wilma | Xfce v: 4.18.1 | 6.8.0-45-generic arch: x86_64 bits | Intel Core i9-14900HX | 32 Go | 1: Intel Raptor Lake-S UHD Graphics 2: NVIDIA AD104M [GeForce RTX 4080 Max-Q / Mobile]

Avatar du membre
Armaggion
Messages : 172
Enregistré le : jeu. 22 août 2024 16:48

Re: Problème avec la commande sed

Message par Armaggion »

Super ! Amuse-toi bien :)
Pc : Desktop | Linux Mint 22 Wilma | Cinnamon | 6.8.0-41-generic | Intel Core i5-6600K | 16GB | Intel HD Graphics 530 / i915 + NVIDIA GA104 [GeForce RTX 3070] / 550.107.02

Répondre