让 awk 打印带有关键字的行,但只在一个范围内
Getting awk to print a line with a keyword, but only within a range
我正在使用 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 单行代码获取 Mediasize 和类型,但它 returns Providers 和 Consumers Mediasize: 因为搜索字符串出现在两个部分中:
$ geom part list da0 | awk '/Mediasize:/ { print } /[ ]+type:/ { print }'
61872754688
freebsd-ufs
61872793600
我可以使用此命令将输出限制为仅介于 Providers: 和 Consumers:
之间的行
$ 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 } /[ ]+type:/ { print } }'
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 程序的输出通过管道传输到另一个程序可以得到我想要的东西,但这似乎是一种混乱。
$ geom part list da0 | awk '/Providers:/,/Consumers:/' | awk '/Mediasize:/ { print } /[ ]+type:/ { print }'
61872754688
freebsd-ufs
理想情况下,我想从单个 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)?:"" } /[ ]type:/ { print (flag==1)?:"" }'
61872754688
freebsd-ufs
关于如何让解决方案 #1 或 #2 起作用的任何想法,或者我可能忽略的另一个解决方案?
未测试:
/Mediasize/ { print }
/type/ { print }
/Consumers/ { exit }
对于那些对最终结果感兴趣的人,我能够将 user448810 的答案付诸实践并获得我想要的输出。
命令:
geom part list mmcsd0 | awk 'BEGIN { printf "{" } /Name/ { printf "%s\n \"%s\": { ", (++count==1)?"":",", } /Mediasize/ { printf "\"size\": %s, ", } / type:/ { printf "\"type\": \"%s\" }", } /Consumers/ { exit } END { printf "\n}\n" }'
输出:
{
"mmcsd0s1": { "size": 52383744, "type": "fat32lba" },
"mmcsd0s2": { "size": 31052026368, "type": "freebsd" }
}
你好!
您可以使用 flag,例如:
awk '/Providers/ {f=1; next} f && /Mediasize/{print ; f=0}
这可以理解为匹配Providers
后,找到Mediazise
和return第二个字段。
我正在使用 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 单行代码获取 Mediasize 和类型,但它 returns Providers 和 Consumers Mediasize: 因为搜索字符串出现在两个部分中:
$ geom part list da0 | awk '/Mediasize:/ { print } /[ ]+type:/ { print }'
61872754688
freebsd-ufs
61872793600
我可以使用此命令将输出限制为仅介于 Providers: 和 Consumers:
之间的行$ 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 } /[ ]+type:/ { print } }'
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 程序的输出通过管道传输到另一个程序可以得到我想要的东西,但这似乎是一种混乱。
$ geom part list da0 | awk '/Providers:/,/Consumers:/' | awk '/Mediasize:/ { print } /[ ]+type:/ { print }'
61872754688
freebsd-ufs
理想情况下,我想从单个 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)?:"" } /[ ]type:/ { print (flag==1)?:"" }'
61872754688
freebsd-ufs
关于如何让解决方案 #1 或 #2 起作用的任何想法,或者我可能忽略的另一个解决方案?
未测试:
/Mediasize/ { print }
/type/ { print }
/Consumers/ { exit }
对于那些对最终结果感兴趣的人,我能够将 user448810 的答案付诸实践并获得我想要的输出。
命令:
geom part list mmcsd0 | awk 'BEGIN { printf "{" } /Name/ { printf "%s\n \"%s\": { ", (++count==1)?"":",", } /Mediasize/ { printf "\"size\": %s, ", } / type:/ { printf "\"type\": \"%s\" }", } /Consumers/ { exit } END { printf "\n}\n" }'
输出:
{
"mmcsd0s1": { "size": 52383744, "type": "fat32lba" },
"mmcsd0s2": { "size": 31052026368, "type": "freebsd" }
}
你好!
您可以使用 flag,例如:
awk '/Providers/ {f=1; next} f && /Mediasize/{print ; f=0}
这可以理解为匹配Providers
后,找到Mediazise
和return第二个字段。