문자열을 일치시킨 후 삽입하는 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에서 설명한 대로 교체를 하드코딩할 수 있습니다. 그러나 "채우고 잊어버리는" 유형의 작업을 원하는 경우 다음 단계를 따라야 합니다.
- 검색을 정의하고 문자열을 바꿉니다.
- 포함된 내용에 관계없이 sed 명령을 다시 조작할 필요가 없도록 이러한 문자열의 이스케이프 버전을 준비하세요.
- 원래 문자열 대신 이스케이프된 문자열을 사용하여 명령을 실행합니다.
# 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
설명하다
- 교체를 수행하려는 적절한 범위를 선택하십시오. 귀하의 경우에는 빈 줄의 [Service]... 줄 내에 있습니다. 이렇게 하면 원하지 않는 영역을 변경할 가능성이 줄어듭니다.
- 범위 내에 있으면 관심 있는 선에 초점을 맞춥니다. 귀하의 경우에는 ExecStart=로 시작하는 선에 있습니다.
- 여기서는 원시 변수 대신 이스케이프된 변수를 사용하고 작은 따옴표를 큰 따옴표로 바꾸고... 데이터를 큰 따옴표에서 다시 작은 따옴표로 바꿉니다. (인용세계를 행복하게 해주세요)
답변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
(&는 일치하는 문자열입니다)