sed regex issue

J'essaie de replace une string dans un file:

$RELEASE = '1234'; 

Les espaces entre RELEASE et le symbole = peuvent être des espaces OU des tabulations. Les guillemets autour du numéro de version peuvent être simples ou doubles.

Je suis en train de supposer des espaces et des guillemets simples pour le moment juste pour essayer de le faire fonctionner:

 sed 's/$RELEASE[[:space:]]*\=[[:space:]]*'\''[0-9]*'\'';/$RELEASE = '\''1234'\'';/g' config.ini > config.ini 

Donc, après beaucoup de travail, cela fonctionne. Mais seulement si la string est des espaces (comme apposé aux tabs) et des guillemets simples comme apposé aux doubles. Voici ce que j'ai jusqu'ici pour essayer d'aborder les tabs …:

 sed 's/$RELEASE([[:space:]]|\t)*\=([[:space:]]|\t)*'\''[0-9]*'\'';/$RELEASE = '\''1234'\'';/g' config.ini > config.ini 

Je viens de lire que / t n'est pas supporté dans la plupart des expressions régulières sed … Est-ce vrai? Y a-t-il un rlocation de type [[: tab:]]? (J'ai essayé ça)

Toute aide serait appréciée.

Je n'ai pas de problème avec [[:space:]] . Voici un petit exemple vraiment stupide montrant le rlocation mixte des espaces et des tabs:

 $ echo -e 'A \t \t B' | sed 's/A[[:space:]]*B/WORKED/' WORKED 

Vous pouvez également utiliser \s ce qui est souvent préférable avec les grandes strings sed parce que c'est beaucoup plus court:

 $ echo -e 'A \t \t B' | sed 's/A\s*B/WORKED/' WORKED 

Quoi qu'il en soit, je pense que votre problème actuel échappe à ces guillemets simples gênants. Je trouve que le moyen le plus simple est de sortir de la string de guillemet simple et d'avoir un guillemet simple entre guillemets puis (si nécessaire) returnner dans la guillemet simple. Bash concaténera automatiquement tout cela pour vous.

 $ echo 'This is a nice ssortingng and this is a single quote:'"'"' Nice?' This is a nice ssortingng and this is a single quote:' Nice? 

Ainsi, tout l'espace que nous avons sauvegardé avec \s est sur le point d'être détruit par cette situation de méga-citation:

 $ echo -e '$RELEASE \t = '"'"'1234'"'"';' |\ sed 's/$RELEASE\s*=\s*'"'"'[0-9]*'"'"'\;/REPLACEMENT/' 

Bien sûr, il y a un argument selon lequel (comme cela ressemble à un script PHP), vous pourriez peut-être supposer que si la ligne commence avec $RELEASE[\s=]+ vous pouvez simplement replace la ligne entière. Pas toujours vrai (toute l'application pourrait être une ligne hideuse) mais cela rend votre search et votre rlocation plus acceptable:

 sed 's/$RELEASE[\s=]*.*/REPLACEMENT/' 

Et oui, les règles générales d'utilisation sed s'appliquent. Ne faites pas écho dans un éditeur de stream (comme sed ) et redirigez-le dans ce file. Si cela fonctionne, vous pouvez facilement bash le file.

Soit utiliser l'argument -i (fonctionne pour sed ) ou le pipe dans une application comme une éponge (qui est comme une sortie retardée):

 sed -i '...' file sed '...' file | sponge file 

Vous pouvez grouper l'expression et utiliser \1 pour pointer vers le groupe. Par exemple

 sed 's/^\($RELEASE.*=\).*/\1 '"'1234'"'/' config.ini