我正在尝试选择包含受此解决方案启发的特定正则表达式模式的块:
$ blockBEGIN='ID'
$ blockEND='Sector Size'
$ myPATTERN='Ready'
$ cat pdisks-simplified-20230825.log | sed -n "/$blockBEGIN/,/$blockEND/{/$blockEND/"'s/$/\x00/;p}' | grep -z "$myPATTERN" | grep -z -v "$blockEND" | tr -d '\x00'
$
但什么也没有出现。
输入示例:
ID : 0:1:4
Status : Ok
State : Ready
Power Status : Spun Up
Bus Protocol : SAS
Media : HDD
Capacity : 3,725.50 GB (4000225165312 bytes)
Vendor ID : DELL(tm)
Product ID : ST4000NM0023
Serial No. : Z1Z6AAR9
Part Number : TH0529FG212334AI01AGA02
Sector Size : 512B
ID : 0:1:0
Status : Ok
State : Online
Power Status : Not Applicable
Bus Protocol : SATA
Media : SSD
Capacity : 372.00 GB (399431958528 bytes)
Vendor ID : DELL(tm)
Product ID : INTEL SSDSC2BX400G4R
Serial No. : BTHC721403F8400VGN
Part Number : CN065WJJIT200766014OA00
Sector Size : 512B
这是文件中的匹配块pdisks-simplified-20230825.log
,如下所示:
ID : 0:1:4
Status : Ok
State : Ready
Power Status : Spun Up
Bus Protocol : SAS
Media : HDD
Capacity : 3,725.50 GB (4000225165312 bytes)
Vendor ID : DELL(tm)
Product ID : ST4000NM0023
Serial No. : Z1Z6AAR9
Part Number : TH0529FG212334AI01AGA02
Sector Size : 512B
$
这是文件中的一个不匹配的块,pdisks-simplified-20230825.log
如下所示:
ID : 0:1:0
Status : Ok
State : Online
Power Status : Not Applicable
Bus Protocol : SATA
Media : SSD
Capacity : 372.00 GB (399431958528 bytes)
Vendor ID : DELL(tm)
Product ID : INTEL SSDSC2BX400G4R
Serial No. : BTHC721403F8400VGN
Part Number : CN065WJJIT200766014OA00
Sector Size : 512B
$
我怎样才能做到这一点 ?
看来你的“块”是用“空行”分隔的,所以很容易将
awk
它们过滤掉:假设:
ID
和结尾Sector Size
(否则我们需要添加更多逻辑)如果
awk
是一个可接受的解决方案:在哪里:
-v myptn="${myPATTERN}"
- 填充以 bash/OS 变量值awk
命名的变量myptn
RS=""
- 将记录分隔符定义为空行$0 ~ myptn
awk
- 如果记录包含名为的变量中包含的字符串/模式myptn
,则打印记录[注意:这将匹配块内的任何字符串,因此如果 OP 需要更具体,那么我们需要扩展代码]block.log
包含 OP 提供的两个示例块当
myPATTERN="Ready"
这生成时:另一种基于分隔块开始/结束的字符串的方法:
笔记:
bstart
并bend
从该行的第一个字符开始,否则将调用替换index()
为适当的匹配bstart
和bend
bstart
和bend
足够唯一,只能匹配块中的一行这会生成:
使用用于多字符
RS
、RT
多字符和\>
单词边界的 GNU awk,这可能就是您想要做的事情:Perl 可能更适合这种用例,它不需要空行作为分隔符:
假设块之间没有换行符,您可以根据正则表达式将文件分成块,然后将其解析为键/值对。
Ruby 或 Perl 是做到这一点的最佳选择。
这是红宝石:
或者您可以对任何 awk 使用块方法:
或者,
要么打印匹配的块: