Traduire la substitution regex de RegEXR pour fonctionner dans un script bash
-
21-12-2019 - |
Question
J'essaie de créer une commande de substitution d'expression régulière dans un script bash, mais après avoir joué avec des guillemets simples, des guillemets doubles et des caractères d'échappement, je m'arrache les cheveux.J'utilise RegEXR pour composer des modèles et j'ai trouvé ce qui suit :
Je recherche :
/\.icon-(.*) {\n\t/gm
et je veux le remplacer par :
if(strpos(\$embedicons,'$1') !== false) { \$svgicons .= <<<'EOD'\n\.$1 {
Ceci remplace ceci :
.icon-basket-14-icon {
background-image: url('data:image/svg+xml;charset=US-ASCII,blahblah');
background-repeat: no-repeat;
}
avec ça:
if(strpos($embedicons,'basket-14-icon') !== false) { $svgicons .= <<<'EOD'
.basket-14-icon {background-image: url('data:image/svg+xml;charset=US-ASCII,blahblah');
background-repeat: no-repeat;
}
Cependant, je n’arrive pas à y parvenir dans un script bash.Je ne suis pas sûr que ce soit pertinent, mais je suis sur OSX Mavericks et j'utilise l'application Terminal.Bien que les modèles de RegExr aient du sens pour moi, une fois que je commence à y échapper, je perds complètement la trace de ce qui se passe.
- Comment s'assurer que l'expression régulière est globale et multiligne ?
- Est-il préférable d'utiliser une autre option que l'expression régulière intégrée ?
- Existe-t-il une ressource en ligne qui enseigne les regex (bash) pour compléter les noobs ?
- Y a-t-il un modèle de groupe qui correspond à tout (y compris les espaces et les Newlines) jusqu'à une chaîne donnée de personnages comme un astérisque (*)?
Je ne cherche évidemment pas l'aumône, car ce problème me hante régulièrement...J'adorerais apprendre les regex et résoudre mes problèmes en apprenant et j'ai étudié quelques exemples en ligne, mais ils semblent beaucoup trop avancés.Peut-être existe-t-il un générateur en ligne comme RegExr qui se traduit en versions de modèles d'expressions régulières compatibles bash et PHP ?
MISE À JOUR/SOLUTION :
Ce qui suit semble fonctionner pour moi dans le terminal OSX Mavericks :
sed "s|\.icon-\(.*\) {|if(strpos(\$embedicons,'\1') !== false) { \$svgicons \.= <<<'EOD' \.\1 {|g"
La solution
Je suggérerais d'utiliser sed
pour ce genre de remplacement, cette ligne fera ce que vous voulez :
sed "s/^.icon-\(.*\) {$/if(strpos(\$embedicons,'\1') !== false) { \$svgicons .= <<<'EOD'\n.\1 {/"g input_file.txt
fichier_entrée.txt :
.icon-basket-14-icon {
background-image: url('data:image/svg+xml;charset=US-ASCII,blahblah');
background-repeat: no-repeat;
}
Sortir:
if(strpos($embedicons,'basket-14-icon') !== false) { $svgicons .= <<<'EOD'
.basket-14-icon {
background-image: url('data:image/svg+xml;charset=US-ASCII,blahblah');
background-repeat: no-repeat;
}
Avec le -r
(expression régulière étendue) défini, il vous suffit d'échapper aux accolades littérales et aux signes dollar variables dans votre exemple.
Concernant vos questions :
- le
g
drapeau poursed
le rend mondial.Qu'entends-tu exactement par "multiligne" ?La sortie de nouvelles lignes est facile en utilisant , la correspondance entre les lignes est un peu plus complexe carsed
fonctionne ligne par ligne.Une technique courante consiste à remplacer toutes les nouvelles lignes du fichier/des données par un espace réservé, à effectuer l'expression régulière/la substitution en gardant l'espace réservé à l'esprit, puis à remplacer à nouveau l'espace réservé par des nouvelles lignes. sed
est probablement votre meilleur choix pour les trucs de type regex.Vous pouvez trouver de la documentation en ligne, celle-ci est assez complète : http://www.grymoire.com/Unix/Sed.html
Pour la dernière partie, en utilisant (.*)
capturera tout, il vous suffira alors de gérer les nouvelles lignes et de vous assurer que vous échappez correctement à votre chaîne de fin.
fichier de test :
testing data with space -
and newlines /'\ *** ends
there
Commande (tr
échange les nouvelles lignes contre les tildes et vice-versa) :
tr '\n' '~' < testfile | sed -r 's/(.*)\*\*\*.*/\1/g' | tr '~' '\n'
Sortir:
testing data with space -
and newlines /'\