Tenho uma lista de itens, da qual desejo selecionar os nomes dos itens ativos:
item {
status: "Active"
properties {
key_a: value
}
id: 42
name: "Foo"
}
item {
status: "Disabled"
properties {
key_b: value
}
id: 12
name: "Bar"
}
item {
status: "Active"
id: 2
name: "Baz"
}
Eu sei que posso extrair os nomes usando grupos de captura com pcregrep
:
$ cat list.txt | pcregrep -o1 -i '^ name: "(.*)"'
Foo
Bar
Baz
Usando uma expressão OR, também posso obter uma lista de valores e nomes de status repetidos:
$ cat list.txt | pcregrep -o2 -i '^ (status|name): "(.*)"'
Active
Foo
Disabled
Bar
Active
Baz
Por fim, preciso filtrar os nomes na lista com base nas linhas anteriores. Como posso fazer isso?
A saída final deve ser:
Foo
Baz
Eu não acho que você pode fazer isso com uma
grep
variação sozinha (reconhecidamente não seipcregrep
). Experimenteawk
:Você pode usar sed também
Como a maior parte do trabalho pesado já foi feito por
pcregrep
, agora você pode passá-lo' so/p para este pequenosed
trecho:o que faz
sed
olhar para 2 linhas de cada vez, em vez do padrão de 1. ON
comando cola a próxima linha ao espaço do padrão separando com uma nova linha\n
. Agora, somente se o sed foi capaz de remover a primeira linha Ativa no espaço de padrão, o espaço de padrão restante será impresso. Esta é uma impressão condicional. Otw nada e-n
deve garantir que não haja impressão automática do espaço do padrão. HTH.Você também pode usar o operador range of
Perl
e restringi-lo com aboolean condition
para lidar com parênteses aninhados{}
em um bloco.Normalmente, alguém escreveria um intervalo em
Perl
as/re1/ ... /re2/
, isso fará comperl
que selecione os blocos que começam com regex/re1/
e terminam nas linhas que satisfazem o regex/re2/
. Poderíamos restringir ainda mais isso, para dizer:/re1/ ... /re2/ && $depth==0
.Isso fará com
perl
que selecione apenas os blocos que possuem uma restrição adicional de profundidade ser zero. Como neste caso, o fim do bloco acontece apenas quando}
é encontrado o que faz com que a contagem de profundidade caia para zero, OTW, o acúmulo de bloco continua além dessa marca.