2016-09-21 7 views
0

私のCentOSサーバーのいくつかを自動化しようとしています。この自動化では、ファイル行を追加、置換、または変更する必要があります。これは、一意の行をグローバル置換または置換することで正常に動作します。他の正規表現の結果の置換

sed -i "s/user \\= apache/user \\= nginx/" file.conf

これは正常に動作しますuser = nginxuser = apacheを置き換えます。

しかし時には、私は他の正規表現の結果の中でこれらのような行を置き換える必要があります。たとえば、ファイル/etc/php-fpm.d/www.confには、同じ設定行が1つのサルバル時間に含まれています。 正規表現を使用すると、私は置換えをしたい部分を簡単にフィルタリングできますが、それを行う方法はわかりません。 [アップデート]まで、私は[ベース]から行を取得することができます

sed -n "/\[base\]/,/\[updates\]/p" /etc/yum.repos.d/CentOS-Base.repo

:この正規表現で

... 
[base] 
name=CentOS-$releasever - Base 
baseurl=http://centos.mirrors.ovh.net/ftp.centos.org/$releasever/os/$basearch/ 
gpgcheck=1 
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 
exclude=postfix 

[updates] 
name=CentOS-$releasever - Updates 
baseurl=http://centos.mirrors.ovh.net/ftp.centos.org/$releasever/os/$basearch/ 
gpgcheck=1 
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 
exclude=postfix 

[extras] 
name=CentOS-$releasever - Extras 
... 

これは、ファイルの一部です。次に、例えばexclude行を変更することができます。しかし、どうすればこれらの行をメインファイルに戻すことができますか?

これは私がこれまで持っているものです。

このスクリプトで
# $BASE contains the lines [base] until [updates] 
BASE=`sed -n "/\[base\]/,/\[updates\]/p" /etc/yum.repos.d/CentOS-Base.repo` 

# Get te line that holds 'exclude' to the $EXCLUDE parameter 
EXCLUDE=`echo "$BASE" | grep "exclude"` 

# Modify EXCLUDE 
EXCLUDE="$EXCLUDE, dovecot" 

# Replace old exclude line in $BASE variable with new one 
BASE=`sed "s/^exclude.*/$EXCLUDE/g" $BASE` 

# Put $BASE back into /etc/yum.repos.d/CentOS-Base.repo 
# ??? 

私は罰金である複数のコマンドでこれを達成しようとしています。これに代わる式が1つだけあればいいでしょう。しかし、もちろんその必要はありません。

+0

'-n'スイッチと' p'コマンドを削除するには、正規表現で定義された 's/search/replace /'のアドレス範囲を追加するだけです。http://stackoverflow.com/documentation/sed/3120/を参照してください。アドレスとアドレスの範囲#t = 201609211113556376005例 – Sundeep

答えて

0
sed -i "/\[base\]/,/\[updates\]/s/^exclude.*/&, dovecot/" 

sedコマンドは、オプションのアドレス、コマンド、コマンドの引数で構成されます。アドレスが存在する場合は、行番号を示す単一の式か、コマンドが適用される行を識別する単一行のパターンか、または開始行と終了行の番号またはパターンを示すコンマ区切り式の対のいずれかですコマンドが適用される範囲。

あなたの前のsedスクリプト("/\[base\]/,/\[updates\]/p")は/\[base\]//\[updates\]/へのアドレス範囲を指定して、コマンドp(プリント)を使用しました。あなただけでは同じ範囲にあなたのs(代替)コマンドを適用することができます

、(何も続い除外 - しかし、行の残りの部分をアップgobbling)exclude.*を置換する(&, dovecotと置換文字列内の&となったすべてのものを意味します一致)。

{ sedコマンドを使用すると、}コマンドで終了するコマンドブロックを開くことができます。これは、あなたができるので、あなたが、もし/他のブロックのようなものを行うことができます:

sed -i -e "/\[base\]/,/\[updates\]/{" \ 
     -e "/\[base\]/h" \ 
     -e "s/^exclude=.*/&, dovecot/" \ 
     -e "/^exclude=/h" \ 
     -e "/\[updates\]/{" \ 
      -e "x" \ 
      -e "/^exclude=/b e" \ 
      -e "i \ 
exclude=dovecot" \ 
      -e ": e" \ 
      -e "x" \ 
     -e "}" \ 
    -e "}" /etc/yum.repos.d/... 

この大きな毛深いsedスクリプトは、以下のん:スクリプト内

  • すべてが[base][updates]ライン間を運行しています。
  • [base]ライン又はexclude=が始まる行は、
  • exclude=, dovecotがそれに
  • [updates]が見られる場合に添付されます始まる行(hコマンドを介して)「ホールド」バッファに入れられる:
    • holdバッファが一時的に回復されます(現在の行をholdバッファと交換するxコマンドを介して)
    • buf FERは、それがexclude=
    • で始まる場合、それは、そうでない場合は(私たちはスキップされていなかったので)e
    • にラベルを付けるために(コマンドb)を分岐して、次の行をスキップしない場合は、行を挿入し、見るためにチェックされますexclude=dovecot
    • ラベルe後に(コマンド:を介して)...
    • スワップ電流線と(再度xを介して)再びholdバッファ

つまり、exclude=行には, dovecotが追加されます。 exclude=行が見られない場合は、新しいexclude=dovecot行が最後に追加されます。あなたが最初-e式を更新してしまう。その場合には、各ブロックの最後に空白行を保証することができれば、/^$//\[base\]/から行く方が便利かもしれないと

注意(通常の場合です)、 -e "/\[updates\]/{"-e '/^$/'{に変更します(また、$がシェルによって解析されないように引用符の変更にも注意してください)。