sed? - Вставить строку после строки со специальными символами в службу Neutron

Я пытаюсь написать сценарий bash, который будет вставлять строку после сопоставления со строкой в ​​

/usr/lib/systemd/system/neutron-server.service

Мне удалось легко сделать это с другими файлами поскольку я просто вставлял переменные в необходимые файлы конфигурации, но этот, похоже, вызывает у меня проблемы.

Я считаю, что ошибка в том, что sed не игнорирует специальные символы. В своей попытке я попытался использовать sed одинарных и двойных кавычек (которые, как я понимаю, предназначены для переменных, но думал, что это может что-то изменить. Есть ли лучший способ сделать это или некоторые специальные флаги sed или синтаксис, которые мне не хватает?

sed ‘/--config-file /etc/neutron/plugin.ini/a\--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini‘ /usr/lib/systemd/system/neutron-server

TL; DR - Вставить

--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini 

После

--config-file /etc/neutron/plugin.ini

Исходный файл

[Unit]
Description=OpenStack Neutron Server
After=syslog.target network.target

[Service]
Type=notify
User=neutron
ExecStart=/usr/bin/neutron-server --config-file /usr/share/neutron/neutron-
dist.conf --config-dir /usr/share/neutron/server --config-file 
/etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --config-dir 
/etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-server -
-log-file /var/log/neutron/server.log
PrivateTmp=true
NotifyAccess=all
KillMode=process
TimeoutStartSec="infinity"

[Install]
WantedBy=multi-user.target

Файл после желаемой команды изменения.

[Unit]
Description=OpenStack Neutron Server
After=syslog.target network.target

[Service]
Type=notify
User=neutron
ExecStart=/usr/bin/neutron-server --config-file /usr/share/neutron/neutron-
dist.conf --config-dir /usr/share/neutron/server --config-file 
/etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --config-
file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini --config-dir 
/etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-server -
-log-file /var/log/neutron/server.log
PrivateTmp=true
NotifyAccess=all
KillMode=process
TimeoutStartSec="infinity"

[Install]
WantedBy=multi-user.target
0
14.06.2017, 00:01
2 ответа

Ваша проблема не в том, что sed неправильно понял символы, а в неправильной команде a, которую вы выбрали для развертывания в этом сценарии. Команда append, a, помещает текст после выделенной строки, тогда как вам нужно вставить некоторый текст внутри выделенной строки. Для этого вам понадобится команда s///.

Если это одноразовая вещь, то вы можете просто жестко закодировать замену, как уже показано DopeGhoti. Но если вам нужна операция типа «заполни и забудь», вам необходимо предпринять следующие шаги:


  1. Определите строки поиска и замены.
  2. Подготовьте экранированную версию этих строк, чтобы независимо от того, что они содержат, вам не нужно было снова возиться с вашей командой sed.
  3. Запустите команду, используя экранированные строки, а не оригиналы.

 # define strings
srch='--config-file /etc/neutron/plugin.ini'
repl='--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini'

# generate their escaped versions
srch_esc=$(printf '%s\n' "$srch"  | sed -e 's|[][^\/.*$]|\\&|g')
repl_esc=$(printf '%s\n' "$repl"  | sed -e 's|[\&/]|\\&|g;$!s/$/\\/')

# run
sed -e '
   /^\[Service]/,/^$/!b
   /^ExecStart=/!b
   '"s/[[:space:]]${srch_esc}[[:space:]]/&${repl_esc} /"'
' yourfile

Объяснение

  1. Выберите соответствующий диапазон, в котором вы хотите, чтобы замена произошла, в вашем случае это находится в пределах строк, охватывающих [Service] ... пустая строка.Поступая таким образом, мы уменьшаем вероятность внесения изменений в нежелательную область.
  2. Оказавшись внутри диапазона, мы обнуляем интересующую нас строку, в вашем случае это строка, начинающаяся с ExecStart=.
  3. Здесь мы просто используем экранированные переменные вместо оригиналов, а также выходим из одинарных кавычек, заключаем в двойные кавычки... помещаем данные... выходим из двойных кавычек, возвращаемся в одинарные кавычки. (чтобы вселенная цитирования была счастлива)
0
28.01.2020, 04:44
sed -i.bak 's_--config-file /etc/neutron/plugin.ini_& --config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini_' /usr/lib/systemd/system/neutron-server.service  

Исходный файл будет сохранен как neutron-server.service.bak. Просто найдите строку, после которой нужно что-то вставить, и замените ее этой строкой, за которой следует вставка. Использование _вместо /для разделителя sedделает сегменты замены до -и после -намного менее пикетными -.

0
28.01.2020, 04:44

Теги

Похожие вопросы