Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Using just shell script, how to search a text file and list all whole blocks of lines that has inside some text (simple grep criteria).

The text file has blocks of lines separated by "-----------------" (precisely, each block start with "\n\n\n--------------------"... about 50 chars "-").

A sample could be:

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

Lets consider the word "banana" the search criteria. So, the blocks listed would be:

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

EDIT:

Testing answers to try awk, like: awk 'BEGIN{RS="\n------------"}/INFO/{print}' where INFO is what was searched for. I cannot get the whole block. So, follows a real sample and the result:

A REAL SAMPLE (including the first 3 new lines):




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

I cannot get the whole block, just the line containing "INFO", like a ordinary grep, either setting or not ORS:

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

NOTES: It is the awk from AIX 7.1, not gawk.

share|improve this question
    
The first block in the sample does not technically start with "\n\n\n---..." – Jeff Schaller Jan 13 at 17:20
    
Yes. Just in the sample. – Luciano Jan 13 at 17:50
    
is perl an option? – Jeff Schaller Jan 13 at 18:27
    
No. Perl isn't an option. – Luciano Jan 13 at 18:28
up vote 3 down vote accepted
awk '
{
  if (/-------------------------------------------------/) {
    if (hold ~ /INFO/) {
      print hold;
    }
    hold="";
  } else {
    hold=hold "\n" $0
  }
} 
END {
  if (hold ~ /INFO/) {
    print hold;
  }
}' file

This uses a 'hold'ing variable (ala sed) to accumulate lines between separated blocks; once a new block (or EOF) is encountered, print the held value only if it matches the /INFO/ pattern.

(re: the older comments, I deleted my previous inadequate awk and perl answers to clean up this answer)

share|improve this answer
    
(assuming GNU awk or mawk) – Stéphane Chazelas Jan 13 at 17:33
    
consider my edits – Luciano Jan 13 at 18:11
    
That is the approach I'm working now and getting success. Of course, my script is a little bit different but the essence is the same. That works. – Luciano Jan 13 at 19:40

Should be quite easy with awk if you don't need all - in the output:

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

alternatively pcregrep:

pcregrep -M '^-+[^-]*banana[^-]*' file
share|improve this answer
    
(assuming GNU awk or mawk) – Stéphane Chazelas Jan 13 at 17:33
    
Could my unhappy results be the awk AIX behavior ? (see my edits) – Luciano Jan 13 at 18:06

If you don't mind the missing leading empty lines, here's a 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
share|improve this answer
    
You can also do this on one line like so: sed -e '/---/b end' -e '//!{H' -e '$!d;$b end' -e '}; : end' -e 'x; /PATTERN/!d' infile (I've found that many people appreciate the one line versions of complex sed commands.) – Wildcard Apr 26 at 1:49

Hope that this script might be of some help, one of the things is that for passing regular expressions, when backslash is involved it must be escaped. it was tested against the input provided as A REAL SAMPLE

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.