web-dev-qa-db-fra.com

Comment utiliser des variables et des non-variables dans une seule commande sed?

J'essaie d'utiliser sed pour remplacer certaines lignes PHP.

Mon problème est que je souhaite remplacer une ligne par PHP variables par une chaîne contenant une variable Bash.

Voici un exemple:

Sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/'$bucketname'.s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php

Comme vous pouvez le constater, je souhaite remplacer $sUrl . $this->_sOutDir (littéralement) par l'URL s3, qui inclut une variable Bash. J'essaie d'utiliser des guillemets doubles mais cela ne fonctionne pas pour moi:

 Sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/"$bucketname".s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php

J'essaie également d'utiliser le s/... complet entre guillemets, mais cela ne fonctionne pas car sed pense que les premières variables sont aussi des variables Bash.

Le résultat est:

return https://.s3.amazonaws.com . $this->_sOutDir . '/';
2
Peter Franke

Vous pouvez aller de deux manières différentes:

  1. Utilisation de guillemets simples: séparez les guillemets simples et référencez la variable (utilisez des guillemets doubles pour empêcher la division de Word et l'expansion du nom de fichier):

    Sudo sed -i 's/$sUrl . $this_sOutDir/https:\/\/'"$bucketname"'.s3.amazonaws.com . $this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php
    
  2. À l'aide de guillemets: échappez les caractères $ à traiter littéralement:

    Sudo sed -i "s/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' /var/www/html/$name/core/oxconfig.php
    

Cependant , le problème est le suivant: si $bucketname contient sed caractères spéciaux/séquences, la commande sed s'interrompra (Dans ce cas, puisque la variable doit être développée dans la section de remplacement, le problème est de savoir si elle contient éventuellement le séparateur, des références arrières accidentelles ou &.

Une façon de contourner ce problème est de supprimer la variable au préalable en évitant les séparateurs, les références arrières accidentelles et les caractères & pour les empêcher d'être interprétés comme tels.

Une autre méthode consiste à utiliser Perl au lieu de sed, en transmettant directement la variable à Perl, qui gérera les caractères spéciaux lors du remplacement (les caractères $ à traiter littéralement doivent être ignorés, même si des guillemets simples sont utilisés avec cette méthode) :

Sudo Perl -i -spe 's/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' -- -bucketname="$bucketname"
$ echo '$sUrl . $this_sOutDir' | Perl -spe 's/\$sUrl . \$this_sOutDir/https:\/\/$bucketname.s3.amazonaws.com . \$this->_sOutDir/g' -- -bucketname="string/with/separators/&/and/accidental\$1backreferences"
https://string/with/separators/&/and/accidental$1backreferences.s3.amazonaws.com . $this->_sOutDir
0
kos