LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-11-2017, 02:04 PM   #1
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,247

Rep: Reputation: 103Reputation: 103
range of lines in sed /@f1(/,/)/


(reference: http://docstore.mik.ua/orelly/unix/sedawk/ch06_02.htm)
I have the following text:
Code:
I want to see @f1(what will happen) if we put the
font change commands @f1(on a set of lines).  If I understand
things (correctly), the @f1(third) line causes problems. (No?).
Is this really the case, or is it (maybe) just something else?

Let's test having two on a line @f1(here) and @f1(there) as
well as one that begins on one line and ends @f1(somewhere 
on another line).  What if @f1(it is here) on the line?
Another @f1(one).
And I have the following:
Code:
/@f1(/,/)/{
	s/@f1(/\\fB/g
	s/)/\\fR/g
}
I'm actually only interested in the first line: "/@f1(/,/)/"
I don't understand what it actually does. If I use sed -n and p, then lines that don't contain $f1... are also shown. What is that?
 
Old 04-11-2017, 10:43 PM   #2
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 792

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
That is a range address. It matches starting with "@f1(" and ending with ")". See here:https://www.gnu.org/software/sed/man...ange-Addresses

I don't get the same results with Lenny's script from the book on my machine. It changes all of the right side parens.
Code:
$ $ cat sed_pat.txt
/@f1(/,/)/{
        s/@f1(/\\fB/g
        s/)/\\fR/g
}

$ sed  -f  sed_pat.txt test.txt 
I want to see \fBwhat will happen\fR if we put the
font change commands \fBon a set of lines\fR.  If I understand
things (correctly\fR, the \fBthird\fR line causes problems. (No?\fR.
Is this really the case, or is it (maybe\fR just something else?

Let's test having two on a line \fBhere\fR and \fBthere\fR as
well as one that begins on one line and ends \fBsomewhere 
on another line\fR.  What if \fBit is here\fR on the line?
Another \fBone\fR.
I think that is explained in the second paragraph of the link above:
Quote:
If the second address is a regexp, then checking for the ending match will start with the line following the line which matched the first address: a range will always span at least two lines ...
 
Old 04-12-2017, 01:11 AM   #3
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,247

Original Poster
Rep: Reputation: 103Reputation: 103
All right, this is a little bit clearer, indeed. But can you explain what is actually going on in this example? Why does it match ALL the lines, after all? Why doesn't it match only the first two lines, for instance? How does it actually parse the text so that it matches everything?

Moreover, why don't the parantheses need escaping? Wouldn't they be interpreted as patterns whose order you can change afterwards using \1 \2, etc.?

P.S. Yes, you're right, I also get the same result as you, not the one shown in the link. I also tried with --posix, but it's the same. Rather weird.

Last edited by vincix; 04-12-2017 at 01:21 AM.
 
Old 04-12-2017, 08:29 AM   #4
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,815

Rep: Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238
The match hits 4 times. The first range includes lines 1 and 2. Then line 3 begins a second range, which includes lines 3 and 4. Lines 6 through 8 are a third matching range. Line 9 begins a 4th range, which continues to EOF since the closing condition is not seen. Overall, everything except the empty line 5 is included.
 
Old 04-12-2017, 08:34 AM   #5
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 792

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
Here's an example that, hopefully, illustrates what rknickols explained above:
Code:
$ cat example.txt
@f1()   # match start - flag set, substitution(s) made
@f1()   # match end - sustitution(s) made, flag unset
@f1()   # match start - flag set, substitution(s) made
)       # match end - sustitution(s) made, flag unset
)       # no match - no action 
@f1()   # match start - flag set, substitution(s) made
@f1()   # match end - sustitution(s) made, flag unset
)       # no match - no action
@f1())) # match start - flag set, substitution(s) made
)       # match end - sustitution(s) made, flag unset
)       # no match - no action

$ sed  "/@f1(/,/)/d" example.txt 
)       # no match - no action 
)       # no match - no action
)       # no match - no action
Quote:
Originally Posted by vincix
Moreover, why don't the parantheses need escaping?
From man 7 regex:
Quote:
Obsolete ("basic") regular expressions differ in several respects. ... The parentheses for nested subexpressions are "\(" and "\)", with '(' and ')' by themselves ordinary characters. ...
 
Old 04-12-2017, 08:43 AM   #6
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,247

Original Poster
Rep: Reputation: 103Reputation: 103
But why do the ranges span only two lines and not more? According to the definition norobro provided, it says that the range spans at least two lines. So why doesn't the range span the first three lines, given that all three contain a string that matches "@f1(/,/)"? (I'm try to address the rest of the explanation later, when they sink in, if ever )
P.S. Now I noticed that you said "6 to 8", which means three lines, but what about the first three lines?

Last edited by vincix; 04-12-2017 at 08:55 AM.
 
Old 04-12-2017, 09:22 AM   #7
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,815

Rep: Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238Reputation: 2238
Unlike a greedy regex match, an address range ends the first time the expression that ends the range is seen. An ending match (which is just a right parenthesis) is seen in line 2, thus ending the first range. Line 4 contains a right parentheses to end the second range. The range that begins with line 6 continues until the right parenthesis in line 8. The range that begins in line 9 is unterminated, since EOF is reached before seeing a line containing a right parenthesis.
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
SED append to a specific range of lines of a file Gener@l Programming 6 04-24-2013 06:56 PM
[SOLVED] SED and Replacing Specific occurrence or Range of Lines bridrod Linux - Newbie 7 08-27-2009 09:59 AM
Sed command to print matching lines and 2 lines above.. DX398 Programming 12 10-01-2008 08:25 AM
Delete specific Range of lines Using sed , awk, grep etc. joyds219 Linux - Newbie 4 03-28-2008 08:59 AM
awk/gawk/sed - read lines from file1, comment out or delete matching lines in file2 rascal84 Linux - General 1 05-24-2006 09:19 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 02:30 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration