我正在嘗試透過管道輸入僅返回由空白行分隔的第一個“段落”或“部分”的內容。我認為我可以根據其他一些答案使用awk
或sed
獲取範圍,但它似乎不起作用。
$ 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 相同的結果。
第一次出現後我該如何取得awk
或sed
停止?
答案1
這正是 awk 有段落模式的原因:
$ awk -v RS= 'NR==1' file
Package: plasma-desktop
Architecture: amd64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y
列印第二筆記錄只是NR==1
to的明顯變化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