让awk打印带有关键字的行,但仅在一个范围内

让awk打印带有关键字的行,但仅在一个范围内,awk,freebsd,Awk,Freebsd,我正在使用FreeBSD的geom命令收集存储设备上的分区信息,并使用awk对其进行过滤。具体来说,我试图从输出的Providers部分提取两行:Mediasize和type 这是未过滤输出的外观: $ geom part list da0 Geom name: da0 modified: false state: OK fwheads: 255 fwsectors: 63 last: 120845263 first: 40 entries: 128 scheme: GPT Providers:

我正在使用FreeBSD的geom命令收集存储设备上的分区信息,并使用awk对其进行过滤。具体来说,我试图从输出的Providers部分提取两行:Mediasize和type

这是未过滤输出的外观:

$ geom part list da0
Geom name: da0
modified: false
state: OK
fwheads: 255
fwsectors: 63
last: 120845263
first: 40
entries: 128
scheme: GPT
Providers:
1. Name: da0p1
   Mediasize: 61872754688 (58G)
   Sectorsize: 512
   Stripesize: 0
   Stripeoffset: 20480
   Mode: r0w0e0
   efimedia: HD(1,GPT,1b5fe285-3be5-11ea-8179-b827ebb30e4e,0x28,0x733f3a8)
   rawuuid: 1b5fe285-3be5-11ea-8179-b827ebb30e4e
   rawtype: 516e7cb6-6ecf-11d6-8ff8-00022d09712b
   label: (null)
   length: 61872754688
   offset: 20480
   type: freebsd-ufs
   index: 1
   end: 120845263
   start: 40
Consumers:
1. Name: da0
   Mediasize: 61872793600 (58G)
   Sectorsize: 512
   Mode: r0w0e0
我可以使用此awk one liner获取Mediasize和类型,但它同时返回提供者和使用者Mediasize:因为搜索字符串出现在两个部分中:

$ geom part list da0 | awk '/Mediasize:/ { print $2 } /[ ]+type:/ { print $2 }'
61872754688
freebsd-ufs
61872793600
我可以使用此命令将输出限制为仅位于提供者和使用者之间的行:

$ geom part list da0 | awk '/Providers:/,/Consumers:/'
Providers:
1. Name: da0p1
   Mediasize: 61872754688 (58G)
   Sectorsize: 512
   Stripesize: 0
   Stripeoffset: 20480
   Mode: r0w0e0
   efimedia: HD(1,GPT,1b5fe285-3be5-11ea-8179-b827ebb30e4e,0x28,0x733f3a8)
   rawuuid: 1b5fe285-3be5-11ea-8179-b827ebb30e4e
   rawtype: 516e7cb6-6ecf-11d6-8ff8-00022d09712b
   label: (null)
   length: 61872754688
   offset: 20480
   type: freebsd-ufs
   index: 1
   end: 120845263
   start: 40
Consumers:
我正在努力解决的是如何将这两者结合到一个awk单行程序中,以打印Mediasize:,但只能从Providers:部分开始

我尝试过这个,但它给了我错误:

$ geom part list da0 | awk '/Providers:/,/Consumers:/ { /Mediasize:/ { print $2 } /[ ]+type:/ { print $2 } }'
awk: syntax error at source line 1
 context is
        /Providers:/,/Consumers:/ { /Mediasize:/ >>>  { <<<
awk: illegal statement at source line 1
awk: syntax error at source line 1
理想情况下,我希望从单个awk单行程序获得输出

我能想到的方法(从最优雅到最不优雅)包括:

1) 以某种方式修复了awk“/Providers:/,/Consumers:/{/Mediasize:/{print$2}/[]+type:/{print$2}}”

2) 一旦遇到Consumers:关键字,就预先退出

3) 遇到Consumers:关键字后,使用标志关闭打印

我可以用一个标志和一个三元运算符使#3工作,但它似乎不那么优雅:

$ geom part list da0 | awk '/Mediasize:/ { print (++flag==1)?$2:"" } /[ ]type:/ { print (flag==1)?$2:"" }'
61872754688
freebsd-ufs

关于如何让解决方案#1或#2发挥作用,或者我忽略的另一个解决方案,有什么想法吗?

未经测试:

/Mediasize/ { print $2 }
/type/      { print $2 }
/Consumers/ { exit }

对于那些对最终结果感兴趣的人,我能够将user448810的答案付诸实施,并获得我想要的输出

命令:

geom part list mmcsd0 | awk 'BEGIN { printf "{" } /Name/ { printf "%s\n  \"%s\": { ", (++count==1)?"":",", $3 } /Mediasize/ { printf "\"size\": %s, ", $2 } / type:/ { printf "\"type\": \"%s\" }", $2 } /Consumers/ { exit } END { printf "\n}\n" }'
输出:

{
  "mmcsd0s1": { "size": 52383744, "type": "fat32lba" },
  "mmcsd0s2": { "size": 31052026368, "type": "freebsd" }
}
奎贝洛

您可以使用,例如:

awk '/Providers/ {f=1; next} f && /Mediasize/{print $2; f=0}
这可以理解为在匹配
提供者之后,找到
Mediazise
并返回第二个字段。

my#2场景的完美解决方案。非常感谢。
awk '/Providers/ {f=1; next} f && /Mediasize/{print $2; f=0}