Imprime todas as linhas correspondentes e a linha anterior sem recuo

3

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?

    
por user146939 10.12.2015 / 22:27

3 respostas

3
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 10.12.2015 / 22:56
5

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
    
por 10.12.2015 / 23:31
2

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 ...

    
por 11.12.2015 / 03:41