Grep couple of consecutive lines if each lines contains certain string


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Grep couple of consecutive lines if each lines contains certain string
# 1  
Old 05-30-2012
Grep couple of consecutive lines if each lines contains certain string

Hello,

I want to extract from a file like :
Code:
20120530025502914 | REQUEST | whatever
20120530025502968 | RESPONSE | whatever
20120530025502985 | RESPONSE | whatever
20120530025502996 | REQUEST | whatever
20120530025503013 | REQUEST | whatever
20120530025503045 | RESPONSE | whatever

I want to extract all groups of 2 lines in which the first line contanis 'REQUEST' and the next line below contains 'RESPONSE'

Basically from the above file I would like to have extracted the following :
Code:
20120530025502914 | REQUEST | whatever
20120530025502968 | RESPONSE | whatever
20120530025503013 | REQUEST | whatever
20120530025503045 | RESPONSE | whatever

(Please note those numbers from the first fields to be able to identify which line I've extracted from the initial file - basically the lines in red from the initial file ).
I'm not completely emty-handed, I have this snippet as a starting point ('stolen' a while ago from internet :P ) :
Code:
nawk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=0 a=1 s="string" file

Which takes the line I that contains the "string" (in my case "REQUEST" ) and the next line after, but i don;t know where to put the condition that the line after to contain the string "RESPONSE" and if so to extract the respective group of 2 lines.

Last edited by Franklin52; 05-30-2012 at 08:03 AM.. Reason: Please use code tags for data and code samples
# 2  
Old 05-30-2012
Try this:
Code:
awk -F"|" '$2 ~ "REQUEST" {s=$0;f=1;next} f && $2 ~ "RESPONSE" {print s RS $0;f=0}' file

These 2 Users Gave Thanks to Franklin52 For This Post:
# 3  
Old 05-30-2012
Quote:
Originally Posted by Franklin52
Try this:
Code:
awk -F"|" '$2 ~ "REQUEST" {s=$0;f=1;next} f && $2 ~ "RESPONSE" {print s RS $0;f=0}' file

Thanks for the response, but I think there must be a syntax error, because I get this :

Code:
 echo kkk | awk -F"|" '$2 ~ "REQUEST" {s=$0;f=1;next} f && $2 ~ "RESPONSE" {print s RS $0;f=0}'
awk: syntax error near line 1
awk: bailing out near line 1

# 4  
Old 05-30-2012
On Solaris use nawk or /usr/xpg4/bin/awk rather than awk
# 5  
Old 05-30-2012
Quote:
Originally Posted by black_fender
I'm not completely emty-handed, I have this snippet as a starting point ('stolen' a while ago from internet :P ) :
Code:
nawk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=0 a=1 s="string" file

I recognise my own code from this post: https://www.unix.com/302098992-post2.html

Since I wrote that in 2006, I notice it has propogated over the internet in other forums and blogs, and now seems to have taken a life of its own.

It's not applicable in this case.
# 6  
Old 05-30-2012
Hi.

I often use cgrep for complex matching and manipulation. It extends some of the features of GNU/grep and is comparable in speed. The heart of the following script is the cgrep. The surrounding code displays the environment under which it was run, as well as comparing results:
Code:
#!/usr/bin/env bash

# @(#) s1	Demonstrate matching on successive lines, cgrep.
# See: http://sourceforge.net/projects/cgrep/

# Section 1, setup, pre-solution, $Revision: 1.25 $".
# Infrastructure details, environment, debug commands for forum posts. 
# Uncomment export command to run script as external user.
# export PATH="/usr/local/bin:/usr/bin:/bin" HOME=""
set +o nounset
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
edges() { local _f _n _l;: ${1?"edges: need file"}; _f=$1;_l=$(wc -l $_f);
  head -${_n:=3} $_f ; pe "--- ( $_l: lines total )" ; tail -$_n $_f ; }
db() { : ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
C=$HOME/bin/context && [ -f $C ] && $C cgrep

set -o nounset
pe

FILE=${1-data1}

# Display sample of data file, with edges or head & tail as a last resort.
db " Section 1: display of input data and expected output."
pe " || start sample [ specimen first:middle:last ] $FILE"
specimen $FILE expected-output.txt 2>/dev/null \
|| { pe "(head/tail)"; head -n 5 $FILE; pe " ||"; tail -n 5 $FILE; }
pe " || end"

# Section 2, solution.
pl " Results:"
db " Section 2: solution."
cgrep -a 'REQUEST.*\n.*RESPONSE' $FILE |
tee f1

# Section 3, post-solution, check results, clean-up, etc.
v1=$(wc -l <expected-output.txt)
v2=$(wc -l < f1)
pl " Comparison of $v2 created lines with $v1 lines of desired results:"
db " Section 3: validate generated calculations with desired results."

pl " Comparison with desired results:"
if [ ! -f expected-output.txt -o ! -s expected-output.txt ]
then
  pe " Comparison file \"expected-output.txt\" zero-length or missing."
  exit
fi
if cmp expected-output.txt f1
then
  pe " Succeeded -- files have same content."
else
  pe " Failed -- files not identical -- detailed comparison follows."
  if diff -b expected-output.txt f1
  then
    pe " Succeeded by ignoring whitespace differences."
  fi
fi

exit 0

producing:
Code:
% ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian GNU/Linux 5.0.8 (lenny) 
bash GNU bash 3.2.39
cgrep ATT cgrep 8.15

 db,  Section 1: display of input data and expected output.
 || start sample [ specimen first:middle:last ] data1
Whole: 5:0:5 of 6 lines in file "data1"
20120530025502914 | REQUEST | whatever
20120530025502968 | RESPONSE | whatever
20120530025502985 | RESPONSE | whatever
20120530025502996 | REQUEST | whatever
20120530025503013 | REQUEST | whatever
20120530025503045 | RESPONSE | whatever

Whole: 5:0:5 of 4 lines in file "expected-output.txt"
20120530025502914 | REQUEST | whatever
20120530025502968 | RESPONSE | whatever
20120530025503013 | REQUEST | whatever
20120530025503045 | RESPONSE | whatever
 || end

-----
 Results:
 db,  Section 2: solution.
20120530025502914 | REQUEST | whatever
20120530025502968 | RESPONSE | whatever
20120530025503013 | REQUEST | whatever
20120530025503045 | RESPONSE | whatever

-----
 Comparison of 4 created lines with 4 lines of desired results:
 db,  Section 3: validate generated calculations with desired results.

-----
 Comparison with desired results:
 Succeeded -- files have same content.

I like awk for its flexilbility (and especially in readability compared to sed for compilcated jobs), but I don't like one-off (nonce) scripts, as well as the fact that my measurements indicate that awk uses about 5 times as much CPU and 5 times as much wall clock time as most members of the grep family for the similar tasks (however, cgrep does use more system time, about twice as much).

See the sourceforge link for the compilable source if it is not in an available repository.

Best wishes ... cheers, drl
# 7  
Old 05-30-2012
@drl, grep cannot do this and I do not think cgrep is present on Solaris, is it? cgrep looks nice though and it is fast indeed. I presume cgrep was tested against gawk, which is one of the slowest awks. Perhaps you could compare it to the fastest awk, which is mawk..

Last edited by Scrutinizer; 05-30-2012 at 11:26 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Remove duplicate consecutive lines with specific string

Hello, I'm trying to remove the duplicate consecutive lines with specific string "WARNING". File.txt abc; WARNING 2345 WARNING 2345 WARNING 2345 WARNING 2345 WARNING 2345 bcd; abc; 123 123 123 WARNING 1234 WARNING 2345 WARNING 2345 efgh; (6 Replies)
Discussion started by: Mannu2525
6 Replies

2. Shell Programming and Scripting

Grep three consecutive lines if each lines contains certain string

say we have : 2914 | REQUEST | whatever 2914 | RESPONSE | whatever 2914 | SUCCESS | whatever 2985 | RESPONSE | whatever 2986 | REQUEST | whatever 2990 | REQUEST | whatever 2985 | RESPONSE | whatever 2996 | REQUEST | whatever 2010 | SUCCESS | whatever 2013 | REQUEST | whatever 2013 |... (7 Replies)
Discussion started by: Saumitra Pandey
7 Replies

3. Shell Programming and Scripting

Grep a string and count following lines starting with another string

I have a large dataset with following structure; C 0001 Carbon D SAR001 methane D SAR002 ethane D SAR003 propane D SAR004 butane D SAR005 pentane C 0002 Hydrogen C 0003 Nitrogen C 0004 Oxygen D SAR011 ozone D SAR012 super oxide C 0005 Sulphur D SAR013... (3 Replies)
Discussion started by: Syeda Sumayya
3 Replies

4. Shell Programming and Scripting

Grep 2 consecutive lines and replace the second line in a file

I have a file lake this cat ex1.txt </DISCOUNTS> <B2B_SPECIFICATION elem="0"> <B2B_SPECIFICATION elem="0"> <DESCR>Netti 2 </DESCR> <NUMBER>D02021507505</NUMBER> </B2B_SPECIFICATION> <B2B_SPECIFICATION elem="1"> <DESCR>Puhepaketti</DESCR>... (2 Replies)
Discussion started by: Dhoni
2 Replies

5. Shell Programming and Scripting

Grep a string from input file and delete next three lines including the line contains string in xml

Hi, 1_strings file contains $ cat 1_strings /home/$USER/Src /home/Valid /home/Review$ cat myxml <projected value="some string" path="/home/$USER/Src"> <input 1/> <estimate value/> <somestring/> </projected> <few more lines > <projected value="some string" path="/home/$USER/check">... (4 Replies)
Discussion started by: greet_sed
4 Replies

6. Shell Programming and Scripting

Merge two non-consecutive lines based on line number or string

This is a variation of an earlier post found here: unixcom/shell-programming-scripting/159821-merge-two-non-consecutive-lines.html User Bartus11 was kind enough to solve that example. Previously, I needed help combining two lines that are non-consecutive in a file. Now I need to do the... (7 Replies)
Discussion started by: munkee
7 Replies

7. Shell Programming and Scripting

Print lines between two lines after grep for a text string

I have several very large file that are extracts from Oracle tables. These files are formatted in XML type syntax with multiple entries like: <ROW> some information more information </ROW> I want to grep for some words, then print all lines between <ROW> AND </ROW>. Can this be done with AWK?... (7 Replies)
Discussion started by: jbruce
7 Replies

8. Shell Programming and Scripting

grep string & a few lines after

i need to grep a STRING_A & the next few lines after the STRING_A example file: STRING_A yada yada line 1 line 2 STRING_B yada yada line 1 line 2 line 3 STRING_A yada yada line 1 line 2 line 3 line 4 STRING_A yada yada line 1 line 2 line 3 line 4 (7 Replies)
Discussion started by: ashterix
7 Replies

9. Shell Programming and Scripting

Grep string but also it will show the next 5 lines

Hi experts, I want to grep a number 9366109380 from a file but it will also show me the next 5 lines. Below is the example- when i grep 989366109380, i can also see the next 5 lines. Line 1. <fullOperation>MAKE:NUMBER:9366109380:PPAY2;</fullOperation> Line 2.... (10 Replies)
Discussion started by: thepurple
10 Replies

10. Shell Programming and Scripting

grep string & next n lines

need help on this. let say i hv 1 file contains as below: STRING Description bla bla bla Description yada yada yada Data bla bla Data yada yada how do i want to display n lines after the string? thanks in advance! (8 Replies)
Discussion started by: ashterix
8 Replies
Login or Register to Ask a Question