You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何筛选blockBEGIN与blockEND间含指定正则模式的文本块?

问题描述

我尝试用sed+grep组合筛选包含指定正则模式的文本块,设置了以下变量和命令:

$ 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

需要筛选出的符合条件的文本块(包含Ready):

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

不符合条件的文本块(不包含Ready):

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

请问该如何正确实现需求?


解决方案

原命令的问题出在grep -z -v "$blockEND"这一步:它会把包含Sector Size的内容全部过滤掉,但每个目标块的结尾恰好是Sector Size行,导致最终无输出。

以下是两种可行的修复方案:

方法1:纯sed实现(推荐)

直接用sed完成块定位+模式筛选逻辑,无需额外工具:

blockBEGIN='ID'
blockEND='Sector Size'
myPATTERN='Ready'

sed -n "/$blockBEGIN/{:a;N;/$blockEND/!ba;/$myPATTERN/p}" pdisks-simplified-20230825.log

逻辑说明:

  1. /blockBEGIN/{...}:匹配到ID行时,执行后续逻辑
  2. :a;N;/blockEND/!ba:循环读取后续行,直到匹配到Sector Size,将整个块读入模式空间
  3. /myPATTERN/p:如果当前块包含Ready,则输出整个块

方法2:修复原sed+grep组合

保留原块分割逻辑,调整过滤和格式转换步骤:

blockBEGIN='ID'
blockEND='Sector Size'
myPATTERN='Ready'

cat pdisks-simplified-20230825.log | sed -n "/$blockBEGIN/,/$blockEND/{/$blockEND/s/$/\x00/;p}" | grep -z "$myPATTERN" | tr '\x00' '\n'

调整点:

  • 移除grep -z -v "$blockEND",避免过滤掉块的结尾行
  • 将tr -d '\x00'改为tr '\x00' '\n',把块间的空分隔符换回换行,保证输出格式正常

内容的提问来源于Stack Exchange,提问作者SebMa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:35:39