2010-06-29 6 views
16

J'ai essayé de mettre ce qui suit dans mon Makefile:Comment utiliser sed dans un Makefile

@if [ $(DEMO) -eq 0 ]; then \ 
    cat sys.conf | sed -e "s#^public_demo[\s=].*$#public_demo=0#" >sys.conf.temp; \ 
else \ 
    cat sys.conf | sed -e "s#^public_demo[\s=].*$#public_demo=1#" >sys.conf.temp; \ 
fi 

mais quand je lance faire, je reçois l'erreur suivante:

sed: -e expression #1, char 30: unterminated `s' command 

Si je exécuter les lignes exactes qui contiennent sed dans la console, ils se comportent correctement. Pourquoi ai-je cette erreur et comment le problème peut-il être résolu?

+0

Il n'y a pas beaucoup de points à l'aide de chat à l'entrée du tuyau ... ne pourriez-vous utiliser juste stdin redirection dans la commande sed? –

+0

@Platinum Azure: Oui, peut-être. C'est juste une version que j'ai atteinte en essayant des corrections aléatoires. – Tom

Répondre

21

Il peut s'agir du signe $ dans la substitution interprétée par make en tant que variable. Essayez d'en utiliser deux comme . * $$ # public_demo. Ensuite, make étendra cela à un seul $.

EDIT: Ce n'était que la moitié de la réponse. Comme cristis a répondu: l'autre partie est que l'on doit utiliser des guillemets simples pour empêcher bash d'étendre le signe $ aussi.

6

Je vous suggère d'utiliser des guillemets simples au lieu de guillemets doubles, la $ peut être traité comme un caractère spécial par marque avant d'exécuter sed:

cat sys.conf | sed -e 's#^public_demo[\s=].*$#public_demo=0#' >sys.conf.temp; 
+0

J'ai d'abord utilisé des guillemets simples et je suis passé à des guillemets parce que, moi aussi, j'ai pensé que les guillemets simples étaient le problème. – Tom

+0

En fait, je pense que cristis est correct, peu importe si ma réponse est correcte ou non. $ sera élargi deux fois, je pense: Une fois dans le makefile, par ma réponse, et une fois par bash. L'utilisation de guillemets simples empêchera bash d'étendre le $, mais ne le fera pas. –

+0

En fait, vous aviez les deux droits. L'utilisation de guillemets simples et $$ a résolu le problème. À qui dois-je répondre maintenant? – Tom

0

Utilisez autre chose que # pour séparer les parties.

+0

J'ai utilisé/en premier lieu et commuté à # parce que moi aussi, j'ai pensé que le séparateur était le problème. – Tom

3

La version make dans ma machine est:

$ make --version 
GNU Make 3.81 
Copyright (C) 2006 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. 
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. 

This program built for x86_64-redhat-linux-gnu 

Et la version sed:

$ sed --version 
GNU sed version 4.2.1 

Je dois ajouter backslash pour $ à éviter sed le prendre comme fin de ligne:

cat sys.conf | sed -e 's#^public_demo[\s=].*\$$#public_demo=0#' >sys.conf.temp 
0

un problème que j'avais avec l'utilisation de sed dans un makefile n'est pas traité par les réponses actuelles, donc je vais l'expliquer ici. Je remplissais des variables Bash comme ça: remote_owner=$$($(MAKE) remote.owner) puis en utilisant ces variables dans ma substitution sed. problème est, en raison de la façon alambiquée mes règles sont mises en place, remote_owner pourrait avoir propre production de faire en elle, me donner l'erreur:

sed: -e expression #1, char 69: unknown option to `s' 
make: *** [alter_table_local.sql] Error 1 

par exemple, en ajoutant des messages de débogage, j'ai trouvé local_owner mis à:

make[1]: Entering directory `/home/jcomeau/rentacoder/jh' 
jcomeau 

la réponse a été d'ajouter l'option --silent à faire: remote_owner=$$($(MAKE) --silent remote.owner)

0

J'ai essayé à double signe $$ mais il ne fonctionne pas dans mon problème, peut-être $$$$ ou $$$$$$$$ aurait fonctionné, parce que mon Makefile appelle d'autres Makefile et ainsi de suite. Mais j'ai trouvé une meilleure solution:

Créez un fichier shell replacer.sh dans le même dossier que votre Makefile qui exécute la commande sed.Donnez-bit exécutable avec

chmod +x replacer.sh 

Maintenant, vous pouvez appeler ce fichier dans votre Makefile:

./replacer.sh 
Questions connexes