#1 Le 16/04/2020, à 18:05
- Christophe C
problème sur remplacement de ligne avec sed
Bonjour, je veux remplacer une ligne entière par une autre ligne. Avec plein de variables inside
La commande ci-dessous marche parfaitement (où $NAME contient la chaîne entraînant la suppression de la ligne où elle se trouve ; et ${TableauRetours[3]} contient la ligne de remplacement).
sed -i -r 's/.*'$NAME'.*/'${TableauRetours[3]}'/g' toto.txt
Par contre
sed -i -r 's/.*'$NAME'.*/'${TableauRetours[3]} ${TableauRetours[4]}'/g' toto.txt
ne marche pas. Il ne se passe rien.
Evidemment, c'est l'option 2 qui m'intéresse (avec un espace entre les 2 variables - mais même si je colle les 2 variables sans espace, cela ne marche pas).
J'ai testé des variantes avec simple quote, doubles quotes, combinaisons des 2 .... marchent pas.
Quelqu'un connait-il la syntaxe ?
Dernière modification par Christophe C (Le 17/04/2020, à 07:06)
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#2 Le 16/04/2020, à 18:14
- Watael
Re : problème sur remplacement de ligne avec sed
salut,
sans les entrées (fichier, variables), ça va pas être facile.
ce que je peux dire :
les .* sont inutiles, de même que le g
mais, ça ne devrait pas avoir d'influence sur ton problème.
Dernière modification par Watael (Le 16/04/2020, à 19:44)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#3 Le 16/04/2020, à 18:16
- nany
Re : problème sur remplacement de ligne avec sed
Bonjour,
Essaie avec des doubles quotes sans quoter les variables :
sed -i -r "s/.*$NAME.*/${TableauRetours[3]} ${TableauRetours[4]}/g" toto.txt
Hors ligne
#4 Le 16/04/2020, à 19:29
- kamaris
Re : problème sur remplacement de ligne avec sed
les .* sont inutiles, de même que le g
Non, selon la description qui est faite, je pense que les .* sont nécessaires (hors du cas particulier où $NAME correspond à toute la ligne).
Par contre le g doit bien être inutile.
Sinon, bien que la commande s puisse effectivement faire ça, il y a la commande c qui est plus directement indiquée dans ce cas :
sed -i -r "/$NAME/c\\${TableauRetours[3]} ${TableauRetours[4]}" toto.txt
Hors ligne
#5 Le 16/04/2020, à 19:43
- Watael
Re : problème sur remplacement de ligne avec sed
ah, oui ! en effet, je me suis focalisé sur la recherche de correspondance, comme avec grep, alors qu'il est question de substituer toute la ligne.
oui, oui, bien sûr, il faut les .*
+1 pour la commande c
Dernière modification par Watael (Le 16/04/2020, à 19:44)
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#6 Le 17/04/2020, à 07:28
- Christophe C
Re : problème sur remplacement de ligne avec sed
Merci à tous
@nany : non, marche pas. Mais effectivement, il faut double quoter simplement, sans mes trucs compliqués.
@Kamaris : parfait, en ajoutant le .* ($NAME ne contient pas la ligne entière) :
sed -i -r "/$NAME.*/c \\${TableauRetours[3]} ${TableauRetours[4]}" toto.txt
Super, et merci.
Est-ce que tu peux m'expliquer la syntaxe ?
-i pour écrire le résultat du remplacement
-r pour indiquer qu'on utilise des expressions rationnelles
/$NAME.*/ pour indiquer de remplacer toute la ligne où se trouve la chaine $NAME
Par contre, que veut dire c \\ ?
J'ai vu dans man que c \ signifie remplacer la chaine précédente par la chaine qui suit, mais je n'ai pas bien compris le second \. Je suppose que c'est lui qui indique le début du nouveau texte ? (celui qui remplacera /$NAME.*/)
Dernière modification par Christophe C (Le 17/04/2020, à 07:38)
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#7 Le 17/04/2020, à 10:24
- kamaris
Re : problème sur remplacement de ligne avec sed
Si la proposition de nany ne fonctionne pas, c'est qu'il y a dans les ${TableauRetours[N]} des caractères que la commande s interprète (par exemple « & »), sinon elle devrait fonctionner.
Non, tu n'as pas besoin de rajouter le .* quand tu utilises /…/, car là tu te contentes de regarder si la ligne contient $NAME.
Dès lors que la ligne correspond à cela, le remplacement de toute la ligne est implicitement contenu dans la commande c (contrairement à s/…/…/, qui remplace des chaines de caractères, pas des lignes).
-r signifie expressions régulières étendues (cf. man grep pour un petit laïus sur la différence entre regex simples et étendues).
L'antislash après la commande c permet effectivement de marquer le début de la ligne de remplacement, notamment pour protéger les éventuels blancs en début de ligne.
Ici il est doublé (« \\ ») car l'antislash doit être protégé dans des guillemets doubles, mais de base c'est sed '/…/c\texte de remplacement'.
Hors ligne
#8 Le 17/04/2020, à 11:02
- Christophe C
Re : problème sur remplacement de ligne avec sed
Merci
Ici il est doublé (« \\ ») car l'antislash doit être protégé dans des guillemets doubles
Je n'ai pas compris cette phrase ?
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne
#9 Le 17/04/2020, à 11:46
- kamaris
Re : problème sur remplacement de ligne avec sed
Pour être plus précis, l'antislash doit être protégé dans des guillemets doubles lorsqu'il précède les caractères $, `, ", \, ou <newline> (cf. man bash).
En l'occurrence :
$ var=texte
$ echo sed "/…/c\$var"
sed /…/c$var
$ echo sed "/…/c\\$var"
sed /…/c\texte
$
Hors ligne
#10 Le 17/04/2020, à 15:51
- Christophe C
Re : problème sur remplacement de ligne avec sed
ok
BountySource - Faite un petit don, ponctuel ou récurent, pour soutenir le développement de XFCE.
Timeshift - Sécurité : pensez à paramétrer des points de restauration système.
Euclide : « Ce qui est affirmé sans preuve peut être nié sans preuve ».
Hors ligne