文字列を一致させた後に挿入するbashスクリプトを作成しようとしています。
/usr/lib/systemd/system/neutron-server.service
必要な構成ファイルに変数を挿入したため、他のファイルでも簡単にこれを実行できましたが、これが問題を引き起こしているようです。
バグは、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
(& は一致する文字列です)