sed Range Pattern and 2 lines before Start Pattern


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting sed Range Pattern and 2 lines before Start Pattern
# 1  
Old 11-12-2015
sed Range Pattern and 2 lines before Start Pattern

Hi all,

I have been searching all over Google but I am unable to find a solution for a particular result that I am trying to achieve.

Consider the following input:

Code:
1
2
3
4
5
B4Srt1--Variable-0000
B4Srt2--Variable-1111
Srt
6
7
8
9
10
End
11
12
13
B4Srt1-Variable-12361
B4Srt2-Variable-68931
Srt
14
15
End


I would like to extract 2 lines (these 2 lines can be different) above "Srt" (fixed) till "End"(fixed).

Desired output:

Code:
B4Srt1--Variable-0000
B4Srt2--Variable-1111
Srt
6
7
8
9
10
End
B4Srt1-Variable-12361
B4Srt2-Variable-68931
Srt
14
15
End

I understand that using the sed range pattern can help me on this.

Code:
sed -n '/Srt/,/End/' filename

However, the challenge that I am facing is that only "Srt" is fixed while the two lines above "Srt" always change, therefore I am unable to use them as a pattern. How do I modify the sed command such that I can include the two lines above "Srt", somewhat like grep -B2?

Please help on this.

Last edited by Don Cragun; 11-12-2015 at 05:25 AM.. Reason: Add CODE and ICODE tags.
# 2  
Old 11-12-2015
With sed -n, nothing is printed unless you explicitly ask for it to be printed. Because you didn't anchor the search for Srt to the start of a line and the two lines before the line that just contains the string Srt also contain the string Srtin both cases, your sed command produces the output you want if you add a p flag to the command you showed us:
Code:
sed -n '/Srt/,/End/p' filename

Does it have to be sed? If the lines before the line just containing:
Code:
Srt

can contain arbitrary text not including Srt, this is easier with ed or ex:
Code:
ed -s filename <<-END
	g/^Srt$/.-2,/^End$/p
	q
END

# 3  
Old 11-12-2015
Hi Don,

Actually the Sample Input was made up arbitrarily by me. It does not necessarily contain the string "Srt". Therefore the sed command, which I was trying should not work.

With regards to your suggestion of using "ed" command, that is just perfect and what I was looking for. To be honest, I didn't know this command even existed...though I know it does now. I'll look into the man page of "ed" now.

I'll try to play around with it for now.

Thanks a lot for the quick assistance Don! Really appreciate it!
# 4  
Old 11-12-2015
Hi.

See also non-standard utilty cgrep, which can poduce combinations to obtain the window desired:
Code:
#!/usr/bin/env bash

# @(#) s1	Demonstrate match with start-2 .. end, cgrep
# Utility cgrep source:
# http://sourceforge.net/projects/cgrep/ (verified 2015.11.12)

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C cgrep

# Set beginning and end patterns.
START="^Srt"
END="^End"

FILE=${1-data1}

pl " Input data file $FILE:"
cat $FILE

pl " Results, start=$START, end=$END, expected output to results:"
cgrep -D -2 +w "$END" "$START" $FILE > f1
paste expected-output.txt f1 |
expand -30

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 5.0.8 (lenny, workstation) 
bash GNU bash 3.2.39
cgrep ATT cgrep 8.15

-----
 Input data file data1:
1
2
3
4
5
B4Srt1--Variable-0000
B4Srt2--Variable-1111
Srt
6
7
8
9
10
End
11
12
13
B4Srt1-Variable-12361
B4Srt2-Variable-68931
Srt
14
15
End

-----
 Results, start=^Srt, end=^End, expected output to results:
B4Srt1--Variable-0000         B4Srt1--Variable-0000
B4Srt2--Variable-1111         B4Srt2--Variable-1111
Srt                           Srt
6                             6
7                             7
8                             8
9                             9
10                            10
End                           End
B4Srt1-Variable-12361         B4Srt1-Variable-12361
B4Srt2-Variable-68931         B4Srt2-Variable-68931
Srt                           Srt
14                            14
15                            15
End                           End

One difference between the solutions is that cgrep will not copy the entire file to a scratch file as will many versions of ed, but rather keep just enough to perform the window task. However, for small files that is not significant.

One will probably need to compile the cgrep code (it compiled easily in 32 and 64-bit with gcc). This is an obvious downside if one is not experienced. However, cgrep is a very fast code, as fast as grep. Here are top few codes for searching a 1,777,700 line file with 1100 matches:
Code:
      gogrep   0.07   0.18   0.09     2.57     1.00      1.00     2.25
       cgrep   0.15   0.31   0.14     2.07     2.14      1.72     3.50
        grep   0.15   0.24   0.08     1.60     2.14      1.33     2.00

The utility gogrep is a searching code written in language go: https://sift-tool.org/

Best wishes ... cheers, drl
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

[sed] Finding and sticking the pattern to the beginning of successive lines up to the next pattern

I have a file like below. 2018.07.01, Sunday 09:27 some text 123456789 0 21 0.06 0.07 0.00 2018.07.02, Monday 09:31 some text 123456789 1 41 0.26 0.32 0.00 09:39 some text 456789012 1 0.07 0.09 0.09 09:45 some text 932469494 1 55 0.29 0.36 0.00 16:49 some text 123456789 0 48 0.12 0.15 0.00... (9 Replies)
Discussion started by: father_7
9 Replies

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

3. Shell Programming and Scripting

Sed: printing lines AFTER pattern matching EXCLUDING the line containing the pattern

'Hi I'm using the following code to extract the lines(and redirect them to a txt file) after the pattern match. But the output is inclusive of the line with pattern match. Which option is to be used to exclude the line containing the pattern? sed -n '/Conn.*User/,$p' > consumers.txt (11 Replies)
Discussion started by: essem
11 Replies

4. Shell Programming and Scripting

Sed print range of lines between line number and pattern

Hi, I have a file as below This is the line one This is the line two <\XMLTAG> This is the line three This is the line four <\XMLTAG> Output of the SED command need to be as below. This is the line one This is the line two <\XMLTAG> Please do the need to needful to... (4 Replies)
Discussion started by: RMN
4 Replies

5. Shell Programming and Scripting

sed pattern to delete lines containing a pattern, except the first occurance

Hello sed gurus. I am using ksh on Sun and have a file created by concatenating several other files. All files contain header rows. I just need to keep the first occurrence and remove all other header rows. header for file 1111 2222 3333 header for file 1111 2222 3333 header for file... (8 Replies)
Discussion started by: gary_w
8 Replies

6. Shell Programming and Scripting

How to print range of lines using sed when pattern has special character "["

Hi, My input has much more lines, but few of them are below pin(IDF) { direction : input; drc_pinsigtype : signal; pin(SELDIV6) { direction : input; drc_pinsigtype : ... (3 Replies)
Discussion started by: nehashine
3 Replies

7. Shell Programming and Scripting

How to combine lines within range of pattern

I've a file say having line 1 line 2 (NP line 3 line 4 line 5) line 6 I want to combine lines starting from (NP and ending with ) then it will look like line 1 line 2 (NP line3 line4 line5) line 6 I tried using sed '/(NP/,/)$/ s/\n/ /' but it's not working. Any help please? ... (8 Replies)
Discussion started by: neg
8 Replies

8. Shell Programming and Scripting

sed pattern range

Hi guys, trying to replace a '#' with a ' ' (space) but only between the brackets '(' and ')' N="text1#text2#text3(var1#var2#var3)" N=`echo $N |sed '/(/,/) s/#. //'` echo $N Looking for an output of "text1#text2#text3(var1 var2 var3)" Any ideas? (15 Replies)
Discussion started by: mikepegg
15 Replies

9. Shell Programming and Scripting

sed: Find start of pattern and extract text to end of line, including the pattern

This is my first post, please be nice. I have tried to google and read different tutorials. The task at hand is: Input file input.txt (example) abc123defhij-E-1234jslo 456ujs-W-abXjklp From this file the task is to grep the -E- and -W- strings that are unique and write a new file... (5 Replies)
Discussion started by: TestTomas
5 Replies

10. Shell Programming and Scripting

Help needed in sed range pattern

Hi all, I am using sed for extracting the lines that occurs between the 2 patterns using the following command: sed -n '/pattern1/,/pattern2/' filename The above command has no problem and works fine. But I was wondering if there is a way to quit sed when it has extracted the range at... (3 Replies)
Discussion started by: sank
3 Replies
Login or Register to Ask a Question