sed
não é a ferramenta certa para o trabalho. No entanto, provavelmente ainda podemos fazer isso em sed
:
sed -n '/^ 1 .* 2 .* 3$/,/^ 5$/ { /^ 1 .* 2 .* 3$/ { h }; /^ 4$/ { x; s/.*//; x;}; /^ 5$/ { x; p; x} }' filename | grep -v -e '^$'
Aqui está apenas a parte que adicionei ao seu bloco de intervalo:
/^ 1 .* 2 .* 3$/ { h }; /^ 4$/ { x; s/.*//; x;}; /^ 5$/ { x; p; x}
Leia isto como:
se a linha corresponder a regex /^ 1 .* 2 .* 3$/
e, em seguida, h
(armazenar linha no buffer de retenção)
Se a linha corresponder a regex /^ 4$/
, então x
(buffer de troca, ou seja, fazer operações se aplicam a armazenar buffer em vez de buffer padrão), substitua tudo em buffer de retenção * e x
novamente (para voltar ao buffer padrão)
Se a linha corresponder a ^ 5$/
, mude para o buffer de retenção, p
(imprima o conteúdo do buffer de retenção) e volte para o buffer padrão
* Infelizmente, s/.*//
não exclui linhas no buffer de espera. A exclusão de linhas no buffer de retenção parece difícil, então nos livramos delas, canalizando para o grep -v -e '^$'
.
Atualizar
Esta versão imprime o nome do arquivo após a correspondência (usando o comando F
) e gerencia sem canalizar para grep
. Obrigado Paulo!
sed -n '/^ 1 .* 2 .* 3$/,/^ 5$/ { /^ 1 .* 2 .* 3$/ { h }; /^ 4$/ { x; s/.*//; x;}; /^ 5$/ { x; /^$/ !{ p; F }; x} }' data