Estou tentando selecionar blocos contendo um padrão regexp específico inspirado nesta solução :
$ 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'
$
Mas nada aparece.
Exemplo de entrada:
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
Aqui está um bloco correspondente do pdisks-simplified-20230825.log
arquivo parecido com este:
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
$
E aqui está um bloco não correspondente do pdisks-simplified-20230825.log
arquivo que se parece com isto:
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
$
Como eu posso fazer isso ?
parece que seus "blocos" são delimitados por "linhas vazias", por isso é muito fácil de usar
awk
para filtrá-los:Premissas:
ID
e terminam comSector Size
(caso contrário, precisaremos adicionar um pouco mais de lógica)Se
awk
for uma solução aceitável:Onde:
-v myptn="${myPATTERN}"
- preencha aawk
variável nomeadamyptn
com o valor da variável bash/OSRS=""
- definir separador de registro como linha em branco$0 ~ myptn
- se o registro contiver a string/padrão contido naawk
variável nomeadamyptn
, imprima o registro [ NOTA: isso corresponderá a qualquer string dentro do bloco, portanto, se o OP precisar ser mais específico, precisaremos expandir o código]block.log
contém ambos os blocos de amostra fornecidos pelo OPQuando
myPATTERN="Ready"
isso gera:Outra abordagem baseada em strings que delimitam o início/fim de um bloco:
NOTAS:
bstart
ebend
começa no primeiro caractere da linha, caso contrário, substitua asindex()
chamadas por um apropriado para corresponderbstart
ebend
bstart
ebend
é único o suficiente para corresponder apenas a uma linha em um blocoIsso gera:
Com o GNU awk para limites de vários caracteres
RS
,RT
e\>
palavras, isso pode ser o que você está tentando fazer:Perl pode ser mais adequado para este caso de uso, que não precisa de linhas em branco como separador:
Supondo que não haja quebra de linha entre os blocos, você pode dividir o arquivo em blocos com base em um regex e depois analisá-lo em pares chave/valor.
Ruby ou Perl serão os melhores para fazer isso.
Aqui está um rubi:
Ou você pode usar uma abordagem de bloco com qualquer awk:
Ou,
Imprime o bloco correspondente: