Utilisation de Sed pour développer des variables d'environnement dans des fichiers

StackOverflow https://stackoverflow.com/questions/1609423

  •  05-07-2019
  •  | 
  •  

Question

J'aimerais utiliser Sed pour développer des variables dans un fichier.

Supposons que j'exporte une variable VARIABLE = quelque chose et que je dispose d'un " test " fichier avec les éléments suivants:

I'd like to expand this: "${VARIABLE}"

J'ai essayé des commandes telles que les suivantes, mais en vain:

cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile

Le résultat est le " fichier de sortie " avec la variable toujours non développée:

I'd like to expand this: "something"

Néanmoins, si vous exécutez eval "echo '$ {VARIABLE}' dans la console bash, la valeur" quelque chose " " être répercuté. En outre, j'ai testé et ce modèle est vraiment correspondu.

La sortie souhaitée serait

<*>

Quelqu'un peut-il nous éclairer?

Était-ce utile?

La solution

Considérez votre version d'évaluation:

cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile

La raison pour laquelle cela ne fonctionne pas, c'est parce que cela nécessite une prescience de la part du shell. Le script sed est généré avant que tout modèle ne corresponde, ce qui empêche le shell de le faire à votre place.

Je l'ai fait de plusieurs manières dans le passé. Normalement, j'ai une liste de variables connues et leurs valeurs, et j'ai effectué la substitution à partir de cette liste:

for var in PATH VARIABLE USERNAME
do
    echo 's%${'"$var"'}%'$(eval echo "\$var")'%g'
done > sed.script

cat test | sed -f sed.script > outputfile

Si vous souhaitez mapper des variables de façon arbitraire, vous devez soit traiter l’environnement tout entier (au lieu de la liste fixe des noms de variables, utilisez la sortie de env , modifiée de manière appropriée), ou utilisez Perl ou Python à la place.

Notez que si la valeur d'une variable d'environnement contient une barre oblique dans votre version, vous rencontrerez des problèmes d'utilisation de la barre oblique en tant que séparateur de champ dans la notation s ///. J'ai utilisé le '%' car relativement peu de variables d'environnement l'utilisent - mais certaines machines contiennent des caractères '%' et une solution complète est donc plus délicate. Vous devez également vous soucier des barres obliques inverses dans la valeur. Vous devez probablement utiliser quelque chose comme ' $ (eval echo "\ $$ var" | sed' s / [\%] / \\ & amp; / g ') ' pour échapper aux barres obliques inverses et symboles de pourcentage dans la valeur de la variable d'environnement. Final ride: certaines versions de sed ont (ou avaient) une capacité limitée pour la taille du script - les anciennes versions de HP-UX avaient une limite d'environ 100. Je ne sais pas si c'est toujours un problème, mais il y a cinq ans à peine.

L’adaptation simple du script original se lit comme suit:

env |
sed 's/=.*//' |
while read var
do
    echo 's%${'"$var"'}%'$(eval echo "\$var" | sed 's/[\%]/\\&/g')'%g'
done > sed.script

cat test | sed -f sed.script > outputfile

Cependant, une meilleure solution utilise le fait que vous avez déjà les valeurs dans la sortie de env , afin que nous puissions écrire:

env |
sed 's/[\%]/\\&/g;s/\([^=]*\)=\(.*\)/s%${\1}%\2%/' > sed.script
cat test | sed -f sed.script > outputfile

Ceci est tout à fait plus sûr car le shell n’évalue jamais ce qui ne devrait pas être évalué - vous devez être très prudent avec les métacaractères du shell dans les valeurs de variable. Cette version ne peut éventuellement rencontrer aucun problème si une sortie de env est mal formée, je pense.

Attention - écrire des scripts sed avec sed est une profession de l'ésotérisme, mais elle illustre bien le pouvoir de bons outils.

Tous ces exemples sont négligents car ils ne nettoient pas les fichiers temporaires.

Autres conseils

Peut-être pouvez-vous vous en tirer sans utiliser sed:

$ echo $VARIABLE
something
$ cat test
I'd like to expand this: ${VARIABLE}
$ eval "echo \"`cat test`\"" > outputfile
$ cat outputfile
I'd like to expand this: something

Laissez l’interpolation de variable shell effectuer le travail.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top