![awk 从固定文本开始,直到第一个空行](https://linux22.com/image/170731/awk%20%E4%BB%8E%E5%9B%BA%E5%AE%9A%E6%96%87%E6%9C%AC%E5%BC%80%E5%A7%8B%EF%BC%8C%E7%9B%B4%E5%88%B0%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%A9%BA%E8%A1%8C.png)
我正在尝试通过管道输入仅返回由空行分隔的第一个“段落”或“部分”的内容。我认为我可以根据其他一些答案使用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