Sed заменяет некомментированные строки в bash

Я чувствую, что близок к решению этой проблемы, но не могу туда добраться.

У меня есть скрипт, который ищет, если утилита вызывается в /etc/rc.local, Если это не так, я хочу добавить строку, вызывающую ее прямо перед строкой exit 0 в конце файла. Пока у меня есть это:

sudo sed -i 's/.*exit 0.*/'$UTILITY_PATH'\n&/' /etc/rc.local

Этот вид работает, но также сопоставляет строки с "выходом 0" в качестве комментария - что происходит дальше /etc/rc.local как напоминание пользователям, что сценарий должен заканчиваться этой строкой.

Итак, чтобы быть ясным, следующее должно соответствовать:

exit 0
 exit 0
exit   0   

и так далее. Следующее НЕ должно совпадать:

#exit 0
#     exit 0
#   blah blah "exit 0" blah blah
# exit    0

Может кто-то указать мне верное направление?

3 ответа

Решение

Я думаю, вы хотите это:

sed -r -i 's/^\s*exit\s{1,}[0-9]/foo\n&/' /etc/rc.local

Это соответствует exit [0-9] - возможно пространство впереди и между ними.


Кстати, вы также можете выполнить как поиск, если шаблон найден, так и возможную вставку за один шаг, используя awk:

awk '/foo/{m=1}/^\s*exit\s+[[:digit:]]/&&!m{print "foo"}1' /etc/rc.local

Более новые версии GNU awk Также поддержка в месте редактирования:

awk -i inplace '/foo/{m=1}/^\s*exit\s+[[:digit:]]/&&!m{print "foo"}1' /etc/rc.local

Это вопрос о регулярных выражениях, верно? То, что вы хотите, соответствует exit 0 если ему не предшествует #. Как насчет этого?

sudo sed -i 's/^[^#]*exit 0.*/'$UTILITY_PATH'\n&/' /etc/rc.local

У вас есть "#" в середине переулка? bcaus, если '#' - это первый печатный символ, в котором вы находитесь в очень легком месте: используйте еще одно регулярное выражение (которое здесь очень просто), чтобы определить область действия sed просто так:

sed '/^\W*#/ ! s/something_u_want/whatever_u_want/ ' /etc/rc.local

/^\W*#/ означает, что sed будет применяться только к строкам, выполняющим этот регистр, иначе ничего не будет сделано
восклицание - это просто отрицание, поэтому условия поменялись местами - теперь sed будет применяться только к тем строкам, которые НЕ начинаются с '#'

если # не первый, то... хммм... может быть:

sed '/^[^#]*exit 0/ s/something_u_want/whatever_u_want/ ' /etc/rc.local
Другие вопросы по тегам