Shell-Script

如何用雙引號在前兩行末尾添加屬性?

  • August 20, 2018

我們要添加以下屬性:

-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M

在包含單詞的前兩行 -HBASE_MASTER_OPTS

更改前的範例

more ams-hbase-env-template.txt

export HBASE_MASTER_OPTS=" -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly"    
export HBASE_MASTER_OPTS=" -XX:CMSInitiatingOccupancyFraction=71 -XX:+UseCMSInitiatingOccupancyOnly"
export HBASE_MASTER_OPTS=" -XX:CMSInitiatingOccupancyFraction=72 -XX:+UseCMSInitiatingOccupancyOnly"
export HBASE_MASTER_OPTS=" -XX:CMSInitiatingOccupancyFraction=73 -XX:+UseCMSInitiatingOccupancyOnly"

更改後的範例(預期結果)

export HBASE_MASTER_OPTS=" -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M"    
export HBASE_MASTER_OPTS=" -XX:CMSInitiatingOccupancyFraction=71 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M"
export HBASE_MASTER_OPTS=" -XX:CMSInitiatingOccupancyFraction=72 -XX:+UseCMSInitiatingOccupancyOnly"
export HBASE_MASTER_OPTS=" -XX:CMSInitiatingOccupancyFraction=73 -XX:+UseCMSInitiatingOccupancyOnly"

到目前為止,我所做的是:

sed -i '/HBASE_MASTER_OPTS/ s/$/-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M/' ams-hbase-env-template.txt

但這是不對的,因為:

  1. 我們想要雙引號結束之前的屬性。
  2. 屬性必須僅在變數為 HBASE_MASTER_OPTS 的前兩行。
  3. 如果屬性已經在行,那麼下次它不會再追加了!

擴展史蒂夫的回答:

awk '/HBASE_MASTER_OPTS/&&/ -XX:[+]UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M/{x++;print;next}/HBASE_MASTER_OPTS/&&x<2{gsub(/"$/," -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M\"");x++}1' ams-hbase-env-template.txt

更新:這是一個更易於維護的版本,其中每個字元串只出現一次。

awk 'BEGIN{p="-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M"}{m=0}/HBASE_MASTER_OPTS/{m=1;++x}m&&index($0,p){print;next}m&&x<=2{gsub(/"$/," " p "\"")}1' ams-hbase-env-template.txt

還有一些解釋:

  • 在模式匹配的第一個版本中,[+]用於文字 + 字元,因為否則+會被解釋為特殊字元。

剩下的點是關於第二個版本:

  • BEGIN子句中,p定義了屬性字元串。以下所有條款適用於輸入的行。
  • {m=0}:該子句沒有條件,這意味著它適用於每一行,因此對於每一行,首先m(匹配)將設置為零。
  • /HBASE_MASTER_OPTS/{m=1;++x}:如果一行與HBASE_MASTER_OPTS字元串匹配,m則設置並且我們的行計數器遞增。
  • m&&index($0,p){print;next}: 此子句檢查除了由 指示的匹配之外,m輸入行中是否還包含屬性字元串。在這種情況下index將返回一個非零值。如果是這樣,我們按原樣列印該行(不再添加屬性)並next跳過剩餘的子句並開始處理下一行。請注意,以下條款最初由史蒂夫提供,僅由我改編:
  • m&&x<=2{gsub(/"$/," " p "\"")}:如果我們到達這一點並且我們有一個匹配的行並且我們的計數器沒有超過 2,我們$0通過在終端前面"加上一個空白和我們的屬性字元串來修改(輸入行)。除此之外,不會產生任何輸出,這將由下一個子句完成。
  • 1:這是一個沒有動作的條件(始終為真),這意味著該動作預設列印輸入行。

這個解決方案怎麼樣awk。在問題中創建所需的輸出。

awk '/HBASE_MASTER_OPTS/&&x<2{gsub(/"$/," -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M\"");x++}1' ams-hbase-env-template.txt

線上嘗試!

引用自:https://unix.stackexchange.com/questions/462371