2016-09-21 85 views
0

我試圖爲我的CentOS服務器自動化一些事情。爲了實現這種自動化,我需要添加,替換或修改文件行。這可以通過全局替換或替換獨特的行來正常工作。替換其他正則表達式結果的結果

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

這將替換user = apacheuser = nginx工作正常。

但有時我需要在其他正則表達式的結果中替換這些行。例如,文件/etc/php-fpm.d/www.conf對於一個特定時間包含相同的配置行。 用正則表達式我可以很容易地過濾掉我想替換的部分,但我不知道該怎麼做。

這是文件的一部分:

... 
[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 
... 

有了這個表達式:

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

我可以從基地】,直到[更新]行。然後我可以修改例如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 
# ??? 

在這個腳本中,我試圖用多個命令這是很好的實現這一點。如果只有一個替換表達式,這也會很好。但這當然不是必須的。

+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")中使用的命令p(打印)與/\[base\]/地址範圍爲/\[updates\]/

您可以直接套用您的s(替代)命令相同的範圍,以替代exclude.*(不包括其後內容是什麼 - 但吞噬了該行的其餘部分)與&, dovecot(其中&替換字符串意味着就是一切匹配)。

如果您需要在該地址範圍內執行更復雜的操作,可以使用{ sed命令 - 該命令將打開一個以}命令結束的命令塊。這讓你做這樣的事情的if/else塊,所以你可以這樣做:

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=任何線被置於「保持」緩衝液(通過h命令)
  • 開頭exclude=, dovecot附加到它
  • [updates]看出任何行:
    • hold緩衝區暫時恢復(通過x命令,用hold緩衝區交換當前行)
    • buf FER進行檢查,看它是否與exclude=
    • 開始,如果是的話,跳過下一行通過分支(命令b)標記e
    • 如果沒有(因爲我們沒有跳過),插入行exclude=dovecot
    • 標籤e後(通過命令:)...
    • 交換當前行和再次hold緩衝液(通過x再次)

換句話說:任何exclude=線獲得, dovecot追加;如果沒有看到exclude=行,則在末尾添加新的exclude=dovecot行。

注意,這可能是從/\[base\]//^$/更加有用,如果你能在每個塊的最後保證一個空行(這是正常的情況下),在這種情況下,您將更新第一-e表達以及將-e "/\[updates\]/{"更改爲-e '/^$/'{(還要注意引號中的更改,以使$未被shell解析)。