print chunk of lines only if there is a pattern match in between them


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting print chunk of lines only if there is a pattern match in between them
# 8  
Old 02-20-2011
Code:
awk 'BEGIN{RS="NAME";FS="\n"} /LOCKED/ {print RS $0}' infile

# 9  
Old 02-20-2011
Note: in most awks RS can only be a single character..
# 10  
Old 02-21-2011
@Bartus11, thanks

awesome explanation bartus11.
its clear now.

thanks again.

Quote:
Originally Posted by bartus11
Well I don't know if it would make much sense, because this code is using some quite advanced regex techniques, like look ahead or sequential matching, which require some regex understanding. If you are still interested I can break it down for you.

After giving it a bit of thought I decided to do it anyway Smilie
Code:
perl -n0e 'while (/NAME.*?((?=NAME)|(?=$))/sg) {$x=$&;print $x if $x=~/LOCKED/}' file

-n - load file's contents into $_ variable
-0 - load whole file into $_ variable. Without that perl would divide the file into lines and process them one by one
-e - execute script
while (/NAME.*?((?=NAME)|(?=$))/sg) - keep going through $_ variable (g option), matching blocks of it that start with "NAME" and that have "NAME" right after their end. This is the look ahead part (?=NAME). To match also last block in variable (file), which is starting with "NAME", but there is no "NAME" at the end, there is alternative look ahead match (?=$), that means end of the variable. /s regex option allows . to match newline characters, which allow regex to match through multiple lines. .*? matches non-greedily all the characters that are between "NAME" and before next "NAME". If ? was missing in this expression, regex would perform greedy match, which would match whole variable in single run. While's body is quite easy. $x=$& is assigning recent match to $x variable. It is done to avoid loosing it's contents when /LOCKED/ is run. So now $x consist of block of lines extracted from $_ variable (file's contents), that start with "NAME" and ends just before next "NAME". This block is tested by $x=~/LOCKED/ expression, to check if it contains word LOCKED, and if it does, then print $x is printing it on screen.
# 11  
Old 02-23-2011
Java code in script

Hi Bartus11,

Could you write in a small script instead of command line.

I tried doing the same using script, but did not succeed.

Please find below the script i used.

Code:
#!/usr/bin/perl 
use warnings;
#$path="H:\\01042011.txt";   
  
 open (T01,">H:\\T01.txt" ) || die ("Could not open file. $!");    
    $path=shift @ARGV;        
    
     open (FILE,$path) or die "can not open";                                  
           while (<FILE>) 
           {
             $line=$_;
               while (/ID NUMBER.*?((?=ID NUMBER)|   (?=$))/sg)
               {
               $x=$&;
               print $x if ($x=~/LOCKED/)
               print T01 ($x,"\n");               
               } 
            }
  
close (FILE);    
close (T01);

Quote:
Well I don't know if it would make much sense, because this code is using some quite advanced regex techniques, like look ahead or sequential matching, which require some regex understanding. If you are still interested I can break it down for you.

After giving it a bit of thought I decided to do it anyway Smilie

Code:
perl -n0e 'while (/NAME.*?((?=NAME)|(?=$))/sg) {$x=$&;print $x if $x=~/LOCKED/}' file

-n - load file's contents into $_ variable
-0 - load whole file into $_ variable. Without that perl would divide the file into lines and process them one by one
-e - execute script
while (/NAME.*?((?=NAME)|(?=$))/sg) - keep going through $_ variable (g option), matching blocks of it that start with "NAME" and that have "NAME" right after their end. This is the look ahead part (?=NAME). To match also last block in variable (file), which is starting with "NAME", but there is no "NAME" at the end, there is alternative look ahead match (?=$), that means end of the variable. /s regex option allows . to match newline characters, which allow regex to match through multiple lines. .*? matches non-greedily all the characters that are between "NAME" and before next "NAME". If ? was missing in this expression, regex would perform greedy match, which would match whole variable in single run. While's body is quite easy. $x=$& is assigning recent match to $x variable. It is done to avoid loosing it's contents when /LOCKED/ is run. So now $x consist of block of lines extracted from $_ variable (file's contents), that start with "NAME" and ends just before next "NAME". This block is tested by $x=~/LOCKED/ expression, to check if it contains word LOCKED, and if it does, then print $x is printing it on screen.

Last edited by Franklin52; 02-24-2011 at 03:26 AM.. Reason: Please use code tags
# 12  
Old 02-23-2011
Remember that the whole file has to be loaded into single variable (red code). Your script is splitting it into separate lines. Try my code:
Code:
#!/usr/bin/perl 
use warnings;
#$path="H:\\01042011.txt"; 

open (T01,">H:\\T01.txt" ) || die ("Could not open file. $!"); 
$path=shift @ARGV; 
open (FILE,$path) or die "can not open";
local $/;
$_=<FILE>;
while (/ID NUMBER.*?((?=ID NUMBER)|(?=$))/sg){
  $x=$&;
  print $x if ($x=~/LOCKED/);
  print T01 ($x,"\n");
}
close (FILE); 
close (T01);

# 13  
Old 02-24-2011
skip the red lines and what if "NAME" appears in middle

Thanks Bartus,

Your code is working great.
But i tried using ^NAME to search for NAME at the beginning of the line but it did not give me any output.
as follows:
Code:
while (/^NAME.*?((?=^NAME)|(?=$))/sg){

I used this because I need to catch the details starting from NAME in a new line till another NAME in the new line is faced.

lets say that if the file given has the following data:
It has NAME at the beginning of line and in the middle as well, and also unnecessary lines which are marked in RED.
Code:
NAME                                                                                               ID NUMBER
--------------------------------------------------------------------------------------------------       ---------
abcdefgheija;lksdf                                                                                 11000000 
*** LOCKED *** 
    PARENT                            3887                                                        
    TRAN NO:                                03                                                      
    PARENT NAME
    PARENT 
This line is an excess line.  This is sample
NAME                                                                                               ID NUMBER
-------------------------------------------------------------------------------------------------- ---------
bbcdeqgheija;lksdf                                                                                 11300000 
                                            
    DATE:                            02-MAR-2010                                     
    SOURCE CORRECTION:                      Y                                                             
    SIBLING NAME
As per the current record, this line should not be there in final file.
NAME                                                                                               ID NUMBER
-------------------------------------------------------------------------------------------------- ---------
vbcdewgheija;lksdf                                                                                 10200000 
    
    PARENT NAME                                       
    DATE:                            15-DEC-2010                                      
Here is one more line which is not needed in output.
One more here
2011-2015 data analysis 
NAME                                                                                               ID NUMBER
-------------------------------------------------------------------------------------------------- ---------
cvbcdeegheija;lksdf                                                                                10300000 
                                           
*** LOCKED *** 
    MIDDLE NAME:                                                                                    
    DATE:                            03-JUN-2010                      
<<<<< EOF>>>>

How do I get which starts from NAME and has ***LOCKED*** inside it and it should skip all the red lines.

I really appreciate your help,
Thanks,
Niel.

Last edited by Scott; 02-24-2011 at 04:13 PM.. Reason: Use code tags, please...
# 14  
Old 02-24-2011
Try:
Code:
while (/^NAME.*?((?=^NAME)|(?=\z))/sgm){

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

sed -- Find pattern -- print remainder -- plus lines up to pattern -- Minus pattern

The intended result should be : PDF converters 'empty line' gpdftext and pdftotext?xml version="1.0"?> xml:space="preserve"><note-content version="0.1" xmlns:/tomboy/link" xmlns:size="http://beatniksoftware.com/tomboy/size">PDF converters gpdftext and pdftotext</note-content>... (9 Replies)
Discussion started by: Klasform
9 Replies

2. Shell Programming and Scripting

Match Pattern and print pattern and multiple lines into one line

Hello Experts , require help . See below output: File inputs ------------------------------------------ Server Host = mike id rl images allocated last updated density vimages expiration last read <------- STATUS ------->... (4 Replies)
Discussion started by: tigerhills
4 Replies

3. UNIX for Dummies Questions & Answers

Match Pattern after certain pattern and Print words next to Pattern

Hi experts , im new to Unix,AWK ,and im just not able to get this right. I need to match for some patterns if it matches I need to print the next few words to it.. I have only three such conditions to match… But I need to print only those words that comes after satisfying the first condition..... (2 Replies)
Discussion started by: 100bees
2 Replies

4. Shell Programming and Scripting

awk print pattern match line and following lines

Data: Pattern Data Data Data Data Data Data Data Data Data ... With awk, how do I print the pattern matching line, then the subsequent lines following the pattern matching line. Varying number of lines following the pattern matching line. (9 Replies)
Discussion started by: dmesserly
9 Replies

5. Shell Programming and Scripting

Print lines that do not match the pattern

I need to print the lines that do not match a pattern. I tried using grep -v and sed -n '/pattern/!p', but both of them are not working as I am passing the pattern as variable and it can be null some times. Example ........ abcd...... .........abcd...... .........abcd......... (4 Replies)
Discussion started by: sunny1234
4 Replies

6. Shell Programming and Scripting

Need one liner to search pattern and print everything expect 6 lines from where pattern match made

i need to search for a pattern from a big file and print everything expect the next 6 lines from where the pattern match was made. (8 Replies)
Discussion started by: chidori
8 Replies

7. Shell Programming and Scripting

Print lines before and after pattern match

I am using Solaris, I want to print 3 lines before pattern match pattern 5 lines after pattern match Pattern is abcd to be searched in a.txt. Looking for the solution in sed/awk/perl. Thanks .. Input File a.txt: ================= 1 2 3 abcd 4 5 6 7 8 (7 Replies)
Discussion started by: manuswami
7 Replies

8. Shell Programming and Scripting

print lines with exact pattern match

I have in a file domain.com. 1909 IN A 1.22.33.44 domain.com. 1909 IN A 22.33.44.55 ns1.domain.com. 1699 IN A 33.44.55.66 ns2.domain.com. 1806 IN A 77.77.66.66 I need to "grep" or "awk" out the lines starting with domain.com. as follows. domain.com. 1909 IN A 1.22.33.44 domain.com.... (3 Replies)
Discussion started by: anilcliff
3 Replies

9. Shell Programming and Scripting

sed print all lines after pattern match

HiCan someone show me how to print all lines from a file after a line matching a pattern using sed?Thanks (13 Replies)
Discussion started by: steadyonabix
13 Replies

10. Shell Programming and Scripting

Perl script to match a pattern and print lines

Hi I have a file (say 'file1')and I want to search for a first occurence of pattern (say 'ERROR') and print ten lines in the file below pattern. I have to code it in PERL and I am using Solaris 5.9. I appreciate any help with code Thanks Ammu (6 Replies)
Discussion started by: ammu
6 Replies
Login or Register to Ask a Question