僅在使用“sed”或“awk”匹配 2 個不同模式後才查找並替換文件中的文本

僅在使用“sed”或“awk”匹配 2 個不同模式後才查找並替換文件中的文本

這是此處提出和回答的問題的擴展:使用 sed 僅在第一次出現的模式匹配後查找並替換文件中的文本

問題是:我需要執行查找和替換,但是僅有的第一次出現後pattern1緊接著出現pattern2。這就是pattern3必須進行查找和替換的地方。

使用連結問題中範例文件的變體:

Server 'Test AB'
    option type 'sa'
    option port '1234'
    option timeout '60'

Server 'Test AB'
    option type 'sb'
    option port '1234'
    option timeout '60'

Server 'Test EF'
    option type 'sa'
    option port '1234'
    option timeout '60'

Server 'Test GH'
    option type 'sa'
    option port '1234'
    option timeout '60'

我需要這個:

Server 'Test AB'
    option type 'sa'
    option port '1234'
    option timeout '60'

Server 'Test AB'
    option type 'sb'
    option port '9876'
    option timeout '60'

Server 'Test EF'
    option type 'sa'
    option port '1234'
    option timeout '60'

Server 'Test GH'
    option type 'sa'
    option port '1234'
    option timeout '60'

前兩個Server名字是相同的。每個伺服器的情況option type都不同。我需要匹配特定Server名稱 ( Test AB),然後匹配option type( sb),然後更改連接埠號碼。

我不知道如何使多個模式在邏輯中連接起來AND

有小費嗎?sedawk解決方案是首選(但對於鐵桿頸鬍子尋找真實的挑戰,嘗試用純 BASH 替換來完成。 BASH 5 以上版本就可以了)。謝謝。

答案1

sed允許您在表單中指定位址範圍addr1,addr2。連結的答案使用一個範圍。現在您需要嵌套範圍。

sed "
/^Server 'Test AB'$/,/^$/ {
/option type 'sb'/,/option port '/ s/option port '.*'/option port '2222'/
}" file

這意味著:從(並包括)一行Server 'Test AB'到(並包括)下一個空白行應用裡面的程式碼{}

裡面的程式碼{}意味著:從(並包含)包含應用指令的行option type 'sb'到(並包含)包含option port '應用s/…/…/指令的行。

s/…/…/命令的含義是:在每一行中將第一次出現的option port '.*'.*貪婪地匹配零個或多個字元)替換為option port '2222'

筆記:

  • 幸運的是,我們可以使用空白行來結束範圍。如果沒有它們,我們會很想指定從 到Server的範圍Server。問題是從Server 'Test AB'到下一次出現的第一個範圍Server將包括第二次出現的Server 'Test AB';且同一段程式碼sed偵測到的範圍不能重疊。addr1,addr2實際上,第二次出現的Server 'Test AB'不會被視為新範圍的開始,因此{}不會對該部分中的行執行其中的程式碼。

  • ^$分別是行首和行尾的錨點。我將它們與 一起使用Server 'Test AB',但我故意不將它們與 一起使用option type 'sb'。根據您的需求調整代碼。

  • 我使用雙引號是因為資料包含單引號。通常你需要$用雙引號進行轉義,但這裡我們在/每個$;後面加引號。$/不是 shell 變數的有效名稱,也不是 shell 想要擴展的任何名稱,因此無需轉義$.

相關內容