Edit du 22/05/17 à 12h30 : J'en suis là
Quand je fais :
sed -i -e "s/TRUC:(1000)\*80/TRUC:(1000)\*99/" fichier
Le fichier est correctement modifié. Mais avec le code suivant, ça ne marche pas, le fichier n'est pas modifié :
old_value="(1000)\*80" new_value="(1000)\*99" sed -i -e "s/TRUC:'$old_value'/TRUC:'$new_value'/" fichier
Post original :
J'ai plusieurs fichiers de config. à modifier comme suit :
config.js :
param_un:valeur_1,
param_deux:valeur_2,
Pas trop dur :
param_a_modifier="param_un"
ancienne_valeur="valeur_1"
nouvelle_valeur="valeur_3"
sed -i -e 's/${param_a_modifier}:${ancienne_valeur}/${param_a_modifier}:${nouvelle_valeur/' config.js
Jusque là tout va bien. Sauf que bien sûr, patatra :
ancienne_valeur="(1000)*30"
nouvelle_valeur="(1000)*300"
Je n'ai pas droit à un message d'erreur, mais sed
ne fait rien. Le fichier n'est pas modifié. Je sèche.
# Regexp
Posté par Benoît Sibaud (site web personnel) . Évalué à 5.
Pour sed
"(1000)*30"
signifie une expression rationnelle, valant"(100030"
ou"(1000)30"
ou"(1000)))))…)))))30"
. Il faut échapper*
en\*
.[^] # Re: Regexp
Posté par deuzene (site web personnel) . Évalué à 1. Dernière modification le 20 mai 2017 à 21:26.
Oui, ok pour l'échapement, j'avais cherché de ce côté, merci.
Le hic c'est que je peut pas échapper ce que je ne vois pas, en l’occurrence le contenu de la variable. Je ne peux que nommer la variable dans l'expression
sed
. Ou alors comment faire ?P.-S.: je viens de voir que c'est l'* qui pose souci. Je m'étais focalisé sur les (). Merci, je vais creuser de ce côté.
« Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »
# Shell Parameter Expansion
Posté par Marotte ⛧ . Évalué à 2.
Si ça peut aider :
Pas sûr que ça fonctionne dans ton cas cela dit.
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
[^] # Re: Shell Parameter Expansion
Posté par deuzene (site web personnel) . Évalué à 0.
J'ai essayé avec la forme
${toto//\*/\\*}
et aussi${toto/\*/\\*/}
, maissed
me renvoie :Merci d'avoir essayé.
« Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »
# .
Posté par . . Évalué à 2. Dernière modification le 21 mai 2017 à 06:29.
Il faut échapper les caractères spéciaux des expressions régulières basiques : '[', '*', '^' et '$' ainsi que le caractère d'échappement lui-même et le caractère qui sépare les arguments de la commande de substitution.
Une solution utilisant Awk et qui ne requiert par d'échappements :
Remarquez le 1 à la fin de la commande qui assure que toutes les lignes seront imprimées.
edit: ironiquement, j'ai du échapper le ^ dans le commentaire ^^
edit2: ne pas oublier de déclarer ':' aussi comme séparateur de champs à la sortie (OFS)
[^] # Re: .
Posté par deuzene (site web personnel) . Évalué à 1.
Merci pour la solution avec
awk
. Je vais regarder ça de plus près (c'est dimanche) et je te tiens au jus.« Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »
[^] # Re: .
Posté par . . Évalué à 1. Dernière modification le 21 mai 2017 à 13:59.
Sinon pour échapper des caractères d'une variable :
Le '.' est aussi a échapper, ce que j'ai oubié de préciser dans mon dernier postvar=$(echo "$var" | sed 's,\.\|\[\|\*\|\^\|\$,\\&,g')
[^] # Re: .
Posté par . . Évalué à 1. Dernière modification le 21 mai 2017 à 14:09.
[^] # Re: .
Posté par deuzene (site web personnel) . Évalué à 1.
Quand je fais :
Le fichier est correctement modifié. Mais avec le code suivant, ça ne marche pas, le fichier n'est pas modifié :
Le lapin ne comprend pas !<
« Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »
[^] # Re: .
Posté par . . Évalué à 1.
Les apostrophes sont de trop.
[^] # Re: .
Posté par deuzene (site web personnel) . Évalué à 1.
Même sans les apostrophes le résultat est identique. Le fichier n'est pas modifié. Merci.
« Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »
[^] # Re: .
Posté par . . Évalué à 1.
Pourtant, en enlevant les apostrophes, ca fonctionne chez moi :
ajoute un echo devant sed pour voir le résultat de l'expansion du script sed te paraît correct.
Attention, il faudrait échapper au moins le '&' dans le deuxième argument de s/// qui n'est pas une expression régulière mais une chaîne de substitution qui obéit à d'autres règles.
# pas la bonne chaine ?
Posté par NeoX . Évalué à 2.
parce que dans le premier cas tu cherches et remplaces TRUC:xxxxx par TRUC:yyyyy
dans le 2e cas tu cherches BOT_SLEEP_DELAY:xxxx
pourquoi ne pas avoir une fichier de configuration qui definit
BOT_SLEEP_DELAY=80000 #l'equivalent de 1000 * 80
ce fichier serait appelé par tous les autres fichiers du programme,
et tu n'aurais alors qu'à modifier cette valeur à un seul endroit.
[^] # Re: pas la bonne chaine ?
Posté par deuzene (site web personnel) . Évalué à 1.
Le coup des deux chaînes différentes c'est bien sûr une erreur de copié-collé.
Évidemment il serait plus simple de changer
(1000)*80
par80000
. D'une je n'ai pas vraiment la main sur les fichiers de config., je ne peux que modifier les valeurs. Et deux, le problème se pose ailleurs. Enfin trois, j'aimerais comprendre pour la prochaine fois où ça m'arrivera.« Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »
# Tout simplement
Posté par Flyounet (site web personnel) . Évalué à 1.
[^] # Re: Tout simplement
Posté par deuzene (site web personnel) . Évalué à 1.
Non plus :<
« Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »
# et comme ca ?
Posté par NeoX . Évalué à 2.
parce que le shell va echapper le premier \* au moment de remplir old_value
mais il faut l'echapper une 2e fois pour l'interpreter dans sed.
si tu dois "debugger" des scripts bash, tu peux les lancer avec
bash -x tonscript.sh
ou mettre set -x avant le code à debugger et set +x apres (ou l'inverse je sais jamais
[^] # Re: et comme ca ?
Posté par fearan . Évalué à 3.
oui enfin au lieu d'échapper les truc en cascade, on peut déjà limiter la casse en utilisant les simples ' lors de l'affectation de la variable…
par ailleurs utiliser les [] pour échapper les caractères spéciaux à tendance à être beaucoup plus robuste, notamment dans les cas d'inclusion successive, il ne reste plus qu'à gérer le cas du ] s'il se présente :)
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: et comme ca ?
Posté par deuzene (site web personnel) . Évalué à 1.
Merci. Le fichier contenant la ligne
TRUC:(1000)*80
j'ai essayé :Là ça marchouille, il faudrait que je repasse la moulinette pour supprimer les []. Je vais creuser de ce côté aussi. Pour l'instant je regarde si je ne peux pas faire tout ça avec awk.
Merci.
« Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »
[^] # Re: et comme ca ?
Posté par fearan . Évalué à 2.
pour la new value y a juste pas besoin de protéger les caractères spéciaux par des [] :), c'est juste pour la old_value.
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
# Brute force
Posté par benja . Évalué à 1. Dernière modification le 23 mai 2017 à 00:33.
À priori cela devrait marcher dans la plupart si pas tous les cas (à tester…), l'idée est d'échapper systématiquement tous les caractères par un singleton, ce qui empêche leur interprétation en tant que méta-caractère.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.