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

相关内容