awk 從固定文字開始,直到第一個空白行

awk 從固定文字開始,直到第一個空白行

我正在嘗試透過管道輸入僅返回由空白行分隔的第一個“段落”或“部分”的內容。我認為我可以根據其他一些答案使用awksed獲取範圍,但它似乎不起作用。

$ cat txt
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

$ cat txt |awk '/^Package:/,/^$/'
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

它不應該只返回第一個“部分”嗎? (按照: Grep 從固定文字開始,直到第一個空白行https://www.unix.com/shell-programming-and-scripting/148692-awk-script-match-pattern-till-blank-line.html

  • 如果我使用grep -ve ^$空白行就會被刪除,所以沒有特殊字元。
  • 如果我嘗試提取不同的部分,我會從兩個“部分”中獲取這些部分:

    $ cat txt |awk '/^Package:/,/^Version:/'
    Package: plasma-desktop
    Architecture: amd64
    Version: 4:5.12.9.1-0ubuntu0.1
    Package: plasma-desktop
    Architecture: amd64
    Version: 4:5.12.4-0ubuntu1
    
  • 如果我使用sed -n '/^Package:/,/^$/p'or ,sed -n '/^Package:/,/^Version:/p'我會得到與等效 awk 相同的結果。

第一次出現後我該如何取得awksed停止?

答案1

這正是 awk 有段落模式的原因:

$ awk -v RS= 'NR==1' file
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

列印第二筆記錄只是NR==1to的明顯變化NR==2

$ awk -v RS= 'NR==2' file
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

順便說一句,永遠不要使用範圍表達式 - 它們使解決瑣碎問題的程式碼比使用標誌稍微簡單一些,但如果您的需求發生最輕微的變化,則需要完全重寫或重複條件。因此,任何時候您可能想/begin/,/end/與 sed 或 awk 一起使用/begin/{f=1} f{print} /end/{f=0},而是與 awk 一起使用,這樣您就可以更好地控制何時/如何列印開始/結束行等。

答案2

在 中/begin/,/end/,「操作標誌」在每次找到匹配項時打開,並在找到匹配項/begin/時關閉。/end/也列印帶有“開始”和“結束”的邊界線。

您輸入的結果是(在以下範例中,列印行後面有註解):

  • '/^Package:/,/^$/'
    Package: plasma-desktop        #TURN ON
    Architecture: amd64            #
    Version: 4:5.12.9.1-0ubuntu0.1 #
    Supported: 3y                  #
                                   #TURN OFF
    Package: plasma-desktop        #TURN ON
    Architecture: amd64            #
    Version: 4:5.12.4-0ubuntu1     #
    Supported: 3y                  #
  • '/^Package:/,/^Version:/'
    Package: plasma-desktop        #TURN ON
    Architecture: amd64            #
    Version: 4:5.12.9.1-0ubuntu0.1 #TURN OFF
    Supported: 3y

    Package: plasma-desktop        #TURN ON
    Architecture: amd64            #
    Version: 4:5.12.4-0ubuntu1     #TURN OFF
    Supported: 3y

要僅列印從“Package:”開始的段落,您可以編寫

sed -ne '/^$/q' -e '/^Package:/,$p' file

sed一旦發現空行,就會退出處理文件,因為/^$/q.

awk

awk '/^$/{exit};/^Package:/,0' file

答案3

正如評論者卡西莫多

/begin/,/end/取得與這些正規表示式相符的行,包括邊界線。 begin 開啟列印,end 關閉。空白行後面的行再次打開列印,因為它也有Package:

我意識到我可以使用sed並更改/begin/0,它將從頭開始。由於只有一個開頭,因此只會匹配一次。

$ cat txt |sed -n '0,/^$/p'
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

相關內容