sed? - 특수 문자가 포함된 문자열 뒤에 Neutron 서비스에 대한 줄을 삽입합니다.

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

답변1

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세그먼트 전후의 세그먼트를 덜 엉키게 교체할 수 있습니다.

답변2

문제는 오해되는 문자가 아니라 이 경우 배포하기로 선택한 sed잘못된 명령에 있습니다. a추가 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. 여기서는 원시 변수 대신 이스케이프된 변수를 사용하고 작은 따옴표를 큰 따옴표로 바꾸고... 데이터를 큰 따옴표에서 다시 작은 따옴표로 바꿉니다. (인용세계를 행복하게 해주세요)

답변3

깔끔하게 유지하려면 일치하는 문자열을 변수 A에 넣고 해당 문자열을 변수 B에 삽입하세요.

$ A="--config-file /etc/neutron/plugin.ini"
$ B="--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco_apic.ini"

sed 명령은 다음과 같습니다:

$ sed "s/$A/& $B/" input_file

그러나 A와 B에는 /가 포함되어 있으므로 sed에 대해 서로 다른 구분 기호를 사용해야 합니다.

$ sed  "s#$A#& $B#" input_file

(&는 일치하는 문자열입니다)

관련 정보