imprimindo um bloco de texto que corresponde a um padrão

4

Usando apenas o shell script, como pesquisar um arquivo de texto e listar todos os blocos inteiros de linhas dentro de algum texto (critérios simples do grep).

O arquivo de texto tem blocos de linhas separadas por "-----------------" (precisamente, cada bloco começa com "\n\n\n--------------------" ... cerca de 50 caracteres "-").

Uma amostra pode ser:

-------------------------------
Abracadabra, blablablalbalba
blablablabla, banana



-------------------------------
Text, sample text, sample text, sample text
Text, sample text, sample text, sample text
Text, sample text, sample text, sample text
Text, sample text, sample text, sample text


-------------------------------  
Text, sample text, sample text, sample text
banana. Sample text, sample text, sample text, sample text
Text, sample text, sample text, sample text

Vamos considerar a palavra "banana" como critério de pesquisa. Então, os blocos listados seriam:

-------------------------------
Abracadabra, blablablalbalba
blablablabla, banana


-------------------------------
Text, sample text, sample text, sample text
banana. Sample text, sample text, sample text, sample text
Text, sample text, sample text, sample text

EDITAR:

Testando respostas para tentar o awk, como: awk 'BEGIN{RS="\n------------"}/INFO/{print}' onde INFO é o que foi procurado. Eu não consigo o bloco inteiro. Então, segue uma amostra real e o resultado:

UMA AMOSTRA REAL (incluindo as primeiras 3 novas linhas):




-------------------------------------------------
Diretório separado do nome o arquivo: adis, IWZLM (/home/interx/adis/src/IWZLM.SRC)
Gerando rotina em linguagem C:
(yla5 adis IWZLM -if)
.INFO =>Rotina BLOQUEADA (status 'M'): Geracao ignorada (use -is para ignorar checagem do status)

[  OK-I ] IWZLM (adis) - Lista lay: Geracao ignorada do codigo em C.



-------------------------------------------------
Diretório separado do nome d arquivo: adis, ADISA (/home/interx/adis/src/ADISA.SRC)
Gerando rotina em linguagem C:
(yla5 adis ADISA -if)
.ERRO: Falha inesperada

Compilando o programa:
(ycomp adis ADISA -exe adis/exe/ADISA.temp.exe )
adis/exe/ADISA.temp.exe => adis/exe/ADISA

[  OK   ] ADISA (adis) - Menu A : Gerada e compilada com sucesso.



-------------------------------------------------
Diretório separado do nome o arquivo: adis, ADISD1 (/home/interx/adis/src/ADISD1.SRC)
Gerando rotina em linguagem C:
(yla5 adis ADISD1 -if)
.ATENCAO: Definicao nao localizada

Compilando o programa:
(ycomp adis ADISD1 -exe adis/exe/ADISD1.temp.exe )
adis/exe/ADISD1.temp.exe => adis/exe/ADISD1

[  OK   ] ADISD1 (adis) - Menu : Gerada e compilada com sucesso.

Não consigo obter o bloco inteiro, apenas a linha que contém "INFO", como um grep comum, seja configurando ou não ORS:

$ cat file  | awk 'BEGIN{RS="\n------------"}/INFO/{print}' 
.INFO =>Rotina BLOQUEADA (status 'M'): Geracao ignorada (use -is para ignorar checagem do status)

NOTAS: É o awk do AIX 7.1, não o gawk.

    
por Luciano 13.01.2016 / 18:02

4 respostas

3
awk '
{
  if (/-------------------------------------------------/) {
    if (hold ~ /INFO/) {
      print hold;
    }
    hold="";
  } else {
    hold=hold "\n" $0
  }
} 
END {
  if (hold ~ /INFO/) {
    print hold;
  }
}' file

Isso usa uma variável 'hold'ing (ala sed) para acumular linhas entre blocos separados; uma vez que um novo bloco (ou EOF) for encontrado, imprima o valor retido apenas se ele corresponder ao padrão / INFO /.

(re: os comentários mais antigos, eu apaguei as minhas respostas inadequadas de awk e perl para limpar esta resposta)

    
por 13.01.2016 / 18:24
4

Deve ser muito fácil com awk se você não precisar de todos os - na saída:

awk -vRS='----' '/banana/{print}' file

alternativamente pcregrep :

pcregrep -M '^-+[^-]*banana[^-]*' file
    
por 13.01.2016 / 18:21
4

Se você não se importa com as linhas vazias principais ausentes, aqui está uma sed solution:

sed '/---/b end                      # if line matches pattern branch to : end
//!{H                                # if it doesn't match, append to hold space
$!d                                  # and if not on the last line, delete it
$b end                               # if it's the last line branch to : end
}
: end                                # label end
x                                    # exchange hold buffer and pattern space
/PATTERN/!d                          # if pattern space doesn't match, delete it
' <infile
    
por 13.01.2016 / 19:42
0

Espero que este script possa ser de alguma ajuda, uma das coisas é que, para transmitir expressões regulares, quando a barra invertida está envolvida, ele deve ser escapado. foi testado contra a entrada fornecida como UMA AMOSTRA REAL

parrsel code

#!/usr/bin/nawk -f
BEGIN{ORS=RS="\n\n\n"}   # the record separator is considering three \n
$0~var1{print}           # when record contains var1 print record 

Execution

## the pattern is passed as var1 and is considering the occurrence of OK as a word
parrsel -v var1=paragraphs -vvar1='\<OK\>' data

-------------------------------------------------
Diretório separado do nome o arquivo: adis, IWZLM (/home/interx/adis/src/IWZLM.SRC)
Gerando rotina em linguagem C:
(yla5 adis IWZLM -if)
.INFO =>Rotina BLOQUEADA (status 'M'): Geracao ignorada (use -is para ignorar checagem do status)

[  OK-I ] IWZLM (adis) - Lista lay: Geracao ignorada do codigo em C.



-------------------------------------------------
Diretório separado do nome d arquivo: adis, ADISA (/home/interx/adis/src/ADISA.SRC)
Gerando rotina em linguagem C:
(yla5 adis ADISA -if)
.ERRO: Falha inesperada

Compilando o programa:
(ycomp adis ADISA -exe adis/exe/ADISA.temp.exe )
adis/exe/ADISA.temp.exe => adis/exe/ADISA

[  OK   ] ADISA (adis) - Menu A : Gerada e compilada com sucesso.

HTH

    
por 23.04.2016 / 20:22