LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-14-2010, 05:49 AM   #1
webhope
Member
 
Registered: Apr 2010
Posts: 184

Rep: Reputation: 30
SED behavior


Does somebody know some way how to recognize if sed has nothing found?
 
Old 05-14-2010, 05:59 AM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
Moved this to a new thread, since it did not relate to the thread where it was.

If sed does not find the pattern is was looking for, then it does not take whatever action was specified. The return code is no help because--even if nothing is matched--sed still completes successfully

You might want to post an example to help us better understand the question.
 
Old 05-14-2010, 06:29 AM   #3
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
pixellany, you understand right what I wanted. That is problem for me.

I search file for some strings. If the one string is found then sed changes it. But I do this in while loop with array. It means if sed has nothing find he writes to file data that need not to be written. Nothing changed so I don't want to write to file. It is not effective.

I use this code
Code:
sed -n -i -e "1h;1! H;$ {;g;s@$original_block@$content_block@g;p;}" /boot/grub/test.lst
But I would like sed nothing write to file if sed nothing found (but returned a string).

Last edited by webhope; 05-14-2010 at 06:31 AM.
 
Old 05-14-2010, 06:37 AM   #4
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
Using sed with the "-i" flag causes it to edit the file "in place". If SED makes no changes it think it does not write to the file. Some simple experiments can confirm this.

Not relevant to the question, but--in your example--you do not need the "-e" flag.

AND---I'm glad to see that I am not the only one that likes to write inscrutable SED commands......
 
Old 05-14-2010, 06:49 AM   #5
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by pixellany View Post
"-i" ... it think it does not write to the file.
You want to say that it does not write to file if nothing found?

If so, then OK. Then I think about other thing that I could use.

Is it possible to change the code so it would change the string to "" (empty string) if nothing found? I mean the output to be empty.
 
Old 05-14-2010, 06:54 AM   #6
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
Quote:
You want to say that it does not write to file if nothing found?
You would need to test this....

Quote:
Is it possible to change the code so it would change the string to "" (empty string) if nothing found? I mean the output to be empty.
I don't understand this. I suggest showing an example (before and after)
 
Old 05-14-2010, 07:15 AM   #7
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
1. original string is "Mandriva Linux"
2. Searched string is "(hd0,2)"
3. run sed -n without -i -e options
4. returned output would be:

Code:

(nothing, just empty string)
 
Old 05-14-2010, 08:19 AM   #8
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Quote:
Originally Posted by webhope View Post
1. original string is "Mandriva Linux"
2. Searched string is "(hd0,2)"
3. run sed -n without -i -e options
4. returned output would be:

Code:

(nothing, just empty string)
Hi,

I have not tested this but you could use the t-command for that. The t-command branches only to a specified label if the substitution command issued before made a change. But you might have to put your sed in a script to work with labels, not 100% sure on that.
Code:
sed -i "1h
  1! H
  $ {
    g
    s@$original_block@$content_block@g
    t go_print
    d
:go_print
    p
    }"
Again, I have not tested this and I am not sure if I understood you right. Anyway, the command above should delete every line if no substitution is made.
 
Old 05-14-2010, 08:46 AM   #9
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
crts, thanx for try.

Code:
sed -n "1h;1! H;$ {;g;s@$search@$replacement@g;t go_print;d;:go_print;p;}" /boot/grub/test.lst
It looks it works. However I have a question.

I am not sure if I really need the "1h;1! H;" ... Originally I wanted sed to search and replace multiline string. To search and replace text like
text="Title Linux
kernel (hd0,2) blabla
init blabla
"
for e.g.

text="Title Linux
kernel UUID=asdlkkjaljdhakjsdhakjsd blabla
init blabla
"
(I was inspired here) - but I found problems. I had to replace new line characters on enf of lines. So in real it is not multiline search. Because the text to search in pattern is like this:

text="Title Linux\nkernel \(hd0,2\) blabla\ninit blabla"

So I ask you If I really need the part "1h;1! H;"

Last edited by webhope; 05-14-2010 at 10:29 AM.
 
Old 05-14-2010, 10:19 AM   #10
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
Effectivity of sed

I think it is not possible to use this code to abort writng to file if output is zero length ("").

Code:
output=$( sed -n -e -i "1h;1! H;$ {;g;s@$search@$replacement@g;t go_print;d;:go_print;p;}" /boot/grub/test.lst );
It will still write to file :-( In while loop it would 23 times try to write instead only e.g. 7 times.

Solution?


Code:
output=$( sed -n "1h;1! H;$ {;g;s@$search@$replacement@g;t go_print;d;:go_print;p;}" /boot/grub/test.lst );
The 1st sed could get the output and the next sed could make the second search and replace with changes to file.... But I think this would not be effective in case that there are e.g. 13 searches/replacements. It would not be effective because it would search 23 items and then make 13 searches/replaces + 13 saves.

What are your experiences with efectivitity with sed - search, replace and save. What is the main part that causes the slowdown? Is it search or save actions?
 
Old 05-14-2010, 11:59 AM   #11
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Quote:
Originally Posted by webhope View Post
I think it is not possible to use this code to abort writng to file if output is zero length ("").

Code:
output=$( sed -n -e -i "1h;1! H;$ {;g;s@$search@$replacement@g;t go_print;d;:go_print;p;}" /boot/grub/test.lst );
It will still write to file :-( In while loop it would 23 times try to write instead only e.g. 7 times.

Solution?


Code:
output=$( sed -n "1h;1! H;$ {;g;s@$search@$replacement@g;t go_print;d;:go_print;p;}" /boot/grub/test.lst );
The 1st sed could get the output and the next sed could make the second search and replace with changes to file.... But I think this would not be effective in case that there are e.g. 13 searches/replacements. It would not be effective because it would search 23 items and then make 13 searches/replaces + 13 saves.

What are your experiences with efectivitity with sed - search, replace and save. What is the main part that causes the slowdown? Is it search or save actions?
I don't understand. If you have a file with 23 lines then of course all 23 lines would be processed. As I understood you wanted the lines that do not contain the pattern to be truncated to zero-length, hence deleted.
 
Old 05-14-2010, 02:51 PM   #12
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by crts View Post
As I understood you wanted the lines that do not contain the pattern to be truncated to zero-length, hence deleted.
Yes. I apologize, but I did not realize that the zero lenght will be written to file also. Therefor I consider other way to do it - in two separate commands. 1st sed with -n option to get output value from sed to bash. If the output is some text, then I can to write it with second sed with -i option. But this is not much efective. Because I don't know how many searches will be found. If only little like 3 or 6 even 10 so it is effective. But if 15 - 20 and or all 23, then it is noit effective - U know why - because it searches twice.

Is there some command for sed which could say "if the search is not zero length then write to file (or jump over the write command)"? I ask if is possible to do it as so: I would not use the -i but maybe the W or w in pattern? I am newbie to sed, to I am not sure what I am doing. But maybe it could be solution?
Thanx for advice.
 
Old 05-14-2010, 04:00 PM   #13
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Quote:
Originally Posted by webhope View Post
Is there some command for sed which could say "if the search is not zero length then write to file (or jump over the write command)"? I ask if is possible to do it as so: I would not use the -i but maybe the W or w in pattern? I am newbie to sed, to I am not sure what I am doing. But maybe it could be solution?
Thanx for advice.
Ok, first you need to understand that there is no 'search' result in your script because you simply do not search. What you have is a line that is examined. If it matches a pattern the line is altered by the 's' command, if there is no pattern match the line is not altered by the 's' command. Now if I understand you correctly, you want non matching lines not only to be deleted but in addition completely removed as if they had never been in the file in the first place, right?

Secondly, 'jump over the write command' if line is not altered? That reads like you do not want the line to be kept in the file if there is a pattern match and a substitution took place.

I still assume that you only want to keep modified lines. So why don't you just get rid of the -i option at all and just redirect the output to a new file. With the -n option sed will only print if explicitly told so. If there is no match then the delete command will be executed which will also prevent sed from executing the following print instruction.

[EDIT]
Wait a minute, I just realized that you want to read the entire file into one line and then process this line only. I also remembered your other post about that issue. What is it you are actually trying to do? Do you just want to get rid of root=UUID=<some-big-number> in exchange for root=(hd0,2)? Or is there more? Please specify what your ultimate goal is. I am not sure if reading the entire file into one line is necessary. The example that you linked is only useful if you want to replace multiple lines that are enclosed by markers which are also spread over several lines apart. So what are your markers in your file?

Last edited by crts; 05-14-2010 at 04:32 PM.
 
Old 05-14-2010, 06:21 PM   #14
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by crts View Post
Now if I understand you correctly, you want non matching lines not only to be deleted but in addition completely removed as if they had never been in the file in the first place, right?
No. I think you should better forget about delete of the line. I've made a confusion

I have the menu.lst . There are some blocks (menu items). I don't delete any line. I just wanted a mechanism that will save the script from saving the lines/blocks that was not changed.

Forget the uuids and hds. Let's simplify the thing.

This is the content of file:
"line 1
line 2
line 3
line 4
....
line 22
line 23
"

Every line for one sed command.

Well, now we will change some lines: 1,2,4,22

Final content of file:
"line 1 changed
line 2 changed
line 3
line 4 changed
....
line 22 changed
line 23
"

My 1st try did 23 changes/saves/write commands. Because even lines 3,5-21,23 were not changed sed -i returns a string and makes wroite command to file. Am I right or not?

I I am right then now I want do only 4 changes not 23. It is nonsense to save all changes 23 times if I need call sed 4 times.
 
Old 05-14-2010, 06:29 PM   #15
webhope
Member
 
Registered: Apr 2010
Posts: 184

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by crts View Post
Wait a minute, I just realized that you want to read the entire file into one line and then process this line only.
No. I open whole file to be read by sed, and sed looks for "one line". By "one line" I mean lines of one item or block.
That is the "title Mandriva\nkernel blabla\ninitrd blabla". It is a block in form of one line... I have changed the end of lines to \n. So this is the "line x" as I wrote in precious post.

Conclusion:
I edit whole file, but I do just little changes. The total number of lines in file does not change! The changes are predefined in a array. I do the changes automatically with sed which is within a loop. Sed changes one line/block/menuitem per cycle. But only if some change is made. Sed searches the line/block/menuitem and if matches then replaces and saves

I hope this is clear enough

Last edited by webhope; 05-14-2010 at 06:36 PM.
 
  


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
bash script with grep and sed: sed getting filenames from grep odysseus.lost Programming 1 07-17-2006 11:36 AM
[sed] "Advanced" sed question(s) G00fy Programming 2 03-20-2006 12:34 AM
sed and escaping & in something like: echo $y | sed 's/&/_/g' prx Programming 7 02-03-2005 11:00 PM
strange sed/bash behavior mpdavig Programming 1 07-24-2004 02:27 AM
Insert character into a line with sed? & variables in sed? jago25_98 Programming 5 03-11-2004 06:12 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:11 AM.

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