awk '
!/^[[:blank:]]/ {unindented = $0}
/matching/ && /^[[:blank:]]/ {print unindented; print}
' file
Que lembra a última linha que não começou com espaço em branco. Quando você chegar a uma linha correspondente, use esse valor.
Por exemplo, digamos que eu queira encontrar todas as linhas com "correspondência" e as linhas sem recuo anteriores neste texto.
Container 1
some text
some text
matching text
some text
Container 2
some text
some text
Container 3
some text
matching text
O resultado que eu quero ficaria assim
Container 1
matching text
Container 3
matching text
Isso é possível?
Aqui está uma maneira com sed
:
sed -n '/^[^[:blank:]]/b do # if line is not indented go to label do
//!{ # if line is indented and if it
/matching/H # matches, append it to hold space
}
$b do # if on last line go to label do
b # branch to end of script
: do # label do
x # exchange hold buffer w. pattern space
/\n.*matching/p # if current pattern space matches, print
' infile
Se você deseja também imprimir as linhas não recuadas que correspondem, por exemplo, Container matching stuff
mesmo se nenhuma das linhas no bloco recuado que se segue corresponder, simplesmente mude a última condição para /matching/p
para remover a restrição \n.*
e imprima o espaço padrão mesmo que ele contenha apenas uma (sem recuo ) linha que corresponde a:
sed -n '/^[^[:blank:]]/b do
//!{
/matching/H
}
$b do
b
: do
x
/matching/p
' infile
Aqui está outro sed
:
sed -ne'/^[[:space:]]/H;$x;//!{$!x;//!s/\n.*match/&/p;}' <in >out
Container 1
some text
some text
matching text
some text
Container 3
some text
matching text
Ele considera que um Container é um intervalo contíguo de linhas não em branco que começam com um caractere não-espaço e apenas imprime Contêineres que correspondem à correspondência uma ou mais vezes a partir da segunda linha.
Você pode escrever isso para grep
:
sed ... | grep -E '^([^ ]| .*match)'
... para obter resultados como o seu exemplo ...
Tags grep text-processing awk sed