3

How can extract the lines between two patterns which are not unique ?

Example:-

data of type samplex
name a
property b
data of type samplex
name c
property d
data of type samplex
name e
property f
data of type sampley
name g
property h

I want to search between the pattern "data of type samplex" and get all occurrences of the lines between them.

First occurrence:- 
name a
property b

Second occurrence:-
name c
property d

Third occurrence:- 
name e
property f

For getting the first occurrence alone and when the two patterns are different,

sed '/pattern1/,/pattern2/p;/pattern2/q' <file> will work. 

How can I tweak this command for my requirement?

3
  • what is your expected output ?
    – Rahul
    Commented Sep 7, 2016 at 10:52
  • I'm confused if the sampley in the last one is a typo, or if you want everything from data of type samplex to data of type anything.
    – ilkkachu
    Commented Sep 7, 2016 at 10:56
  • 2
    Please edit your question and show us the exact output you want to see. Do you want to have the string Nth occurrence:- added? Do you want to remove the lines after sampley?
    – terdon
    Commented Sep 7, 2016 at 11:30

4 Answers 4

1
sed 's:data of type samplex:\n:g' File_name -i

This code will replace the said string with newline so that you will get required info. Use -i option to save the changes in original file only.

4
  • This also prints the lines after sampley. I don't think the OP wants that.
    – terdon
    Commented Sep 7, 2016 at 11:30
  • I assume it's typo
    – SHW
    Commented Sep 7, 2016 at 12:29
  • I think not - sample x and sample y, based on what they said they want, but it is not very clear...
    – Zanna
    Commented Sep 7, 2016 at 18:40
  • OP has this line between two patterns which are not unique in question, so I suppose sampley was deliberately added
    – Sundeep
    Commented Sep 8, 2016 at 4:36
1

Does this work for you ?

grep "data of type samplex" -A 2 <file>
1

Based on my possibly wrong interpretation of what you want... Obviously you could shorten it if you can match less than the whole phrase.

sed -n '/data\ of\ type\ samplex/,/data\ of\ type\ sampley/{s/data\ of\ type\ sample[xy]//; p}' file

-n quiet, don't print anything until we want output
[xy] match either x or y here
s/data\ of\ type\ sample[xy]// delete the matched pattern leaving an empty line
p print whatever is left after all that

Output:

name a
property b

name c
property d

name e
property f

I haven't figured out how to add an incremented "Nth occurrence :-" in the case that you want it though

1

Assumption:

  • The input file has various sections demarcated by data of type followed by keyword like samplex, sampley, etc
  • Extracting required: all text falling under particular section

Input file has been modified slightly to reflect corner cases

$ cat ip.txt 
data of type samplex
name a
property b
data of type samplez
name 1
property 2
data of type samplex
name e
property f
data of type sampley
name g
property h
data of type samplex
name c
property d

In solution below, $match is set to 1 if section matches, else 0 when input line is data of type. Then input lines are printed until next section starts. This way a section at end of file is also taken care.

$ perl -ne 'if(/data of type /){$match=/samplex$/} elsif($match){print}' ip.txt
name a
property b
name e
property f
name c
property d

$ perl -ne 'if(/data of type /){$match=/samplez$/} elsif($match){print}' ip.txt
name 1
property 2

$ perl -ne 'if(/data of type /){$match=/sampley$/} elsif($match){print}' ip.txt
name g
property h

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .