I'm trying to pipe into something that will return only the first "paragraph" or "section" separated by a blank line. I thought I could use awk
or sed
to get a range as per some other answers but it doesn't seem to work.
$ 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
Should it not return only the first "section"? (as per:
Grep starting from a fixed text, until the first blank line
and
https://www.unix.com/shell-programming-and-scripting/148692-awk-script-match-pattern-till-blank-line.html)
- If I use
grep -ve ^$
the blank lines get removed, so there's no special characters. -
If I try to extract a different part, I get the parts from both "sections":
$ 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
-
If I use
sed -n '/^Package:/,/^$/p'
orsed -n '/^Package:/,/^Version:/p'
I get the same results as the equivalent awk.
How do I get awk
or sed
to stop after the first occurrence?
Best Answer
This is exactly why awk has a paragraph mode:
and to print the 2nd record is just the obvious change of
NR==1
toNR==2
:Never use range expressions btw - they make code for trivial problems very slightly briefer than using a flag but then if your requirements change in the slightest require a complete rewrite or duplicate conditions. So any time you thing you might want to use
/begin/,/end/
with sed or awk use/begin/{f=1} f{print} /end/{f=0}
with awk instead and that gives you FAR more control on when/how to print the begin/end lines, etc.