ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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).
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......
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.
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:
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?
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.
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.
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?
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.
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.