Подтвердить что ты не робот

Как использовать sed в Makefile

Я попытался поместить следующее в мой 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

но когда я запустил make, я получаю следующую ошибку:

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

Если я запускаю точные строки, содержащие sed в консоли, они ведут себя правильно.

Почему я получаю эту ошибку и как можно устранить проблему?

4b9b3361

Ответ 1

Это может быть знак $подстановки, который интерпретируется make как переменной. Попробуйте использовать два из них, например . * $$ # public_demo. Затем make расширяет это до единственного $.

EDIT: Это была только половина ответа. Как ответили cristis: другая часть состоит в том, что нужно использовать одинарные кавычки, чтобы предотвратить bash от расширения знака $.

Ответ 2

Я предлагаю вам использовать одинарные кавычки вместо двойных кавычек, $ может быть обработан как специальный char make перед запуском sed:

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

Ответ 3

Версия make на моей машине:

$ 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

И версия sed:

$ sed --version
GNU sed version 4.2.1

Я должен добавить обратную косую черту для $, чтобы sed не принимал ее как конец строки:

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

Ответ 4

Используйте что-то еще, чем # для разделения частей.

Ответ 5

одна проблема, с которой я работал с sed в make файле, не отвечает текущими ответами, поэтому я объясню это здесь. Я заполнял переменные Bash, например: remote_owner=$$($(MAKE) remote.owner), а затем используя эти переменные в моей замене sed. проблема из-за запутанного способа настройки моих правил, remote_owner мог бы сделать собственный вывод в нем, давая мне ошибку:

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

например, добавив отладочные сообщения, я обнаружил, что local_owner установлен на:

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

ответ заключался в том, чтобы добавить параметр --silent, чтобы сделать: remote_owner=$$($(MAKE) --silent remote.owner)

Ответ 6

Я пробовал двойной знак $$, но он не работал в моей проблеме, возможно, $$$$ или $$$$$$$$ работал бы, потому что мой Makefile вызывает другие Makefile и т.д. Но я нашел лучшее решение:

Создайте файл оболочки replacer.sh в той же папке, что и ваш Makefile, который выполняет команду sed. Дайте ему исполняемый бит с помощью

chmod +x replacer.sh

Теперь вы можете вызвать этот файл в своем файле Makefile:

./replacer.sh