LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
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 06-08-2014, 07:44 AM   #1
RandyTech
Member
 
Registered: Oct 2010
Posts: 62

Rep: Reputation: 3
SED Multiline edit -- Quit After First Match/Edit


I found this nice multi-line insert command structure using SED and it works perfect except my "unique line" occurs more than once in the target file. I need to insert text only once before the first occurrence of that "unique line":
Code:
sed -e '/^unique line/ i \
First line of text to insert before unique line.\
Second line of text to insert before unique line.\
Third line of text to insert before unique line.
' -i /path/file 1>/dev/null 2>&1
I have tried inserting the SED 'q' command into the code structure using every possible method I can image but cannot get SED to quit after the first edit. Am I just barking up the wrong tree thinking 'q' can be used in this manner? Any ideas?

Further details to the above using this sample /path/file:
Code:
right shoe
foo
left shoe
foo
makes a pair
This is what the sample code above gives me if my "unique line" is "foo":
Code:
right shoe
First line of text to insert before unique line.
Second line of text to insert before unique line.
Third line of text to insert before unique line.
foo
left shoe
First line of text to insert before unique line.
Second line of text to insert before unique line.
Third line of text to insert before unique line.
foo
makes a pair
And this is what I want:
Code:
right shoe
First line of text to insert before unique line.
Second line of text to insert before unique line.
Third line of text to insert before unique line.
foo
left shoe
foo
makes a pair
Thanks in advance for your time!!
 
Old 06-08-2014, 10:00 AM   #2
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware64-15.0
Posts: 6,376

Rep: Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756
Code:
bash-4.3$ cat in4.txt
right shoe
foo
left shoe
foo
makes a pair

bash-4.3$ sed '1,/^foo/ s/foo/First line of text to insert before unique line.\nSecond line of text to insert before unique line.\nThird line of text to insert before unique line.\n&/' in4.txt
right shoe
First line of text to insert before unique line.
Second line of text to insert before unique line.
Third line of text to insert before unique line.
foo
left shoe
foo
makes a pair

Last edited by allend; 06-08-2014 at 10:26 AM. Reason: Use ampersand instead.
 
Old 06-08-2014, 10:32 AM   #3
RandyTech
Member
 
Registered: Oct 2010
Posts: 62

Original Poster
Rep: Reputation: 3
Hi allend and thanks for your reply... but that's cheating ... telling SED where to begin the search.

Ok, not cheating. Technically you solved the question as I presented it. What I failed to mention is the "unique line" might appear anywhere in the source file, so the /path/file could look like this:
Code:
some text
right shoe
foo
left shoe
foo
makes a pair
or it could look like this:
Code:
some text
some other text
more text
right shoe
foo
left shoe
foo
makes a pair
The only thing I can be sure about, I want to insert my lines before the first "foo" line, there will always be more than one "foo" line and I never know where the first "foo" line will appear.

Last edited by RandyTech; 06-08-2014 at 10:35 AM.
 
Old 06-08-2014, 10:41 AM   #4
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware64-15.0
Posts: 6,376

Rep: Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756
Why is confining the address range to the first line through to the first match cheating?
 
Old 06-08-2014, 10:48 AM   #5
RandyTech
Member
 
Registered: Oct 2010
Posts: 62

Original Poster
Rep: Reputation: 3
Oh wait! Sorry allend -- Your solution does work!! But why? I thought the sed '1,/ was telling it to begin on line one. Obviouly I am very confused.
 
Old 06-08-2014, 10:54 AM   #6
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware64-15.0
Posts: 6,376

Rep: Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756
From 'info sed'
Quote:
An address range can be specified by specifying two addresses
separated by a comma (`,'). An address range matches lines starting
from where the first address matches, and continues until the second
address matches (inclusively).

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 (except of
course if the input stream ends).
 
Old 06-08-2014, 11:54 AM   #7
RandyTech
Member
 
Registered: Oct 2010
Posts: 62

Original Poster
Rep: Reputation: 3
Ok, new problem with this new SED line. I was trying to keep my post simple and clear as possible but now its coming back to bite me. The original SED command structure did not have a problem with special characters so for example, this would work fine:
Code:
sed -e '/^unique line/ i \
#First line of text to insert before unique line.\
Second/line/of/text/to/insert before unique line.\
Third line of text to; insert before unique line.
' -i /path/file 1>/dev/null 2>&1
Except of course the original problem, it would insert in front of every instance of the "unique line".
 
Old 06-08-2014, 12:06 PM   #8
RandyTech
Member
 
Registered: Oct 2010
Posts: 62

Original Poster
Rep: Reputation: 3
It seams to be tripping on text that has forward slash:
Quote:
Second/line/of/text/to/insert before unique line.\
 
Old 06-08-2014, 08:15 PM   #9
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware64-15.0
Posts: 6,376

Rep: Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756
Perhaps change the delimiter for the substitute command.
Code:
bash-4.3$ sed '1,/^foo/ s:foo:#First line of text to insert before unique line.\nSecond/line/of/text/to/insert/before/unique/line.\nThird line of text to; insert before unique line.\n&:' in4.txt
right shoe
#First line of text to insert before unique line.
Second/line/of/text/to/insert/before/unique/line.
Third line of text to; insert before unique line.
foo
left shoe
foo
makes a pair
 
Old 06-09-2014, 03:15 AM   #10
RandyTech
Member
 
Registered: Oct 2010
Posts: 62

Original Poster
Rep: Reputation: 3
Quote:
Originally Posted by allend View Post
Perhaps change the delimiter for the substitute command.
That worked except (again) I failed to mention the text would also include the colon, so I changed your colon to a percent and it works like a charm. You are "genius"! Many many thanks for sticking it out with me!!

The final and *working* solution:
Code:
sed '1,/^foo/ s%foo%#First line of text to insert before unique line.\nSecond/line/of/text/to/insert/before/unique/line.\nThird line of text to; insert before unique line.\n&%' in4.txt
I tried substituting the delimiter previously but did not realize the "sed '1,/^foo/ " portion of the command line was a completely separate component unrelated to the "sed 's/word/otherword/' component, so I changed *all* forward slash to percent across the entire command line (except in the 3 lines of text) and of course it failed. Pheew! If I can figure out what that "sed '1,/^foo/ " portion is all about, why we are able to get two completely separate sed components into a single sed command line, and what the '1, is doing exactly then I will have actually learned something here. This "sed" stuff is like playing chess to me. I suck at chess. My brain just doesn't seem to hold the entire image going into these depths. All that aside. Thanks again allend!!
 
  


Reply



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 variable multiline match cptsockpuppet Programming 6 04-30-2012 03:12 PM
Cannot edit blog comment from Android… edit box freezes as it is starting Kenny_Strawn LQ Suggestions & Feedback 3 01-05-2011 06:26 PM
[SOLVED] How do you use sed to edit a file? SparceMatrix Linux - General 3 09-04-2010 03:13 PM
using sed to edit html tkeyser Programming 6 08-20-2009 07:15 PM
SED: edit ip address n1wil Linux - Software 4 01-08-2008 02:18 PM

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

All times are GMT -5. The time now is 05:54 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