LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   sed one-liner: search text in file and replace it. if not present, insert it (https://www.linuxquestions.org/questions/programming-9/sed-one-liner-search-text-in-file-and-replace-it-if-not-present-insert-it-838548/)

pkramerruiz 10-16-2010 05:55 PM

sed one-liner: search text in file and replace it. if not present, insert it
 
As indicated in the subject, I want to search a text.
If the text is present I want to replace it. But if the text is not present, I want to insert it after first line and before last line.

Searched text is:CleanCache "*";
Where * can be anything.

Example: CleanCache "false"; -> CleanCache "true";
If CleanCache "false"; is not present, only insert CleanCache "true"; after first line and before last line.

crts 10-16-2010 09:47 PM

Hi,

although it is possible to do all this with one sed instruction I do not think that this would be the best solution in this case. You would make a mess in the Hold buffer and then by the end would try to modify it with a more or less complicated regex.
Try this instead
Code:

sed -n '/pattern/ q 99' infile
if [[ $? = 99 ]]; then
        sed -r 's/pattern/newpattern/' infile > outfile
else
        sed -r '1 a \
        newpattern
        $ i \
        newpattern
        ' infile > outfile
fi

Easy to understand, without unnecessary complications.

FWIW, here is one possible solution with just one sed. However, this does not *really* qualify as a one-liner.
Code:

# not recommended
sed -nr '1 h; 1 ! H; $ {g;s/pattern/newpattern/;t end; s/^([^\n]*)(.*\n)([^\n]*)$/\1\nnewpattern\2newpattern\n\3/;:end p}' infile > outfile

Both examples assume that there are no empty lines at the beginning and at the end of the file.

ghostdog74 10-16-2010 10:02 PM

use awk
Code:

#! /bin/bash

awk '/CleanCache.*false/{ f=1 }
{ a[++d]=$0 }
END{
  if(!f){
    for(i=1;i<=d;i++){
      if (i==2 || i==(d)){
        a[i]="Cleancache \042true\042\n" a[i]
      }
      print a[i]
    }
  }
}' file


grail 10-17-2010 01:54 AM

Here is an awk alternative:
Code:

awk '/CleanCache.*false/{save = "Cleancache \042true\042";a=1;next}g{print save}{save=$0;g=1}END{if(a)print save;else print "Cleancache \042true\042\n" save}' file

ghostdog74 10-17-2010 03:15 AM

Quote:

Originally Posted by grail (Post 4130099)
Here is an awk alternative:
Code:

awk '/CleanCache.*false/{save = "Cleancache \042true\042";a=1;next}g{print save}{save=$0;g=1}END{if(a)print save;else print "Cleancache \042true\042\n" save}' file

i think OP wants "after the first line" as well

grail 10-17-2010 05:41 AM

My bad :redface: ... I like yours then :)

pkramerruiz 10-17-2010 08:54 AM

Thanks
 
Many many thanks to all for your effort.
@crts, @ghostdog74:
I really need some art of one liner… Because I don’t want to create first a script and after the script has finished, delete the script… Isn it a little redundant and unnecessary?

To help a little: The file I want to edit is "/root/.synaptic/synaptic.conf"
and what I must insert is the following:
CleanCache "true";
AutoCleanCache "true";
delHistory "1";

Its a bit of non-graphical tuning of the synaptic-app!
Cheers & thanks! *Thumbs up**Thumbs up*

grail 10-17-2010 09:32 AM

I am not sure I see the point of this then as it would be a one time edit, why not just open with your favourite editor and do the job?

crts 10-17-2010 09:49 AM

Quote:

Originally Posted by pkramerruiz (Post 4130296)
Many many thanks to all for your effort.
@crts, @ghostdog74:
I really need some art of one liner… Because I don’t want to create first a script and after the script has finished, delete the script… Isn it a little redundant and unnecessary?

To help a little: The file I want to edit is "/root/.synaptic/synaptic.conf"
and what I must insert is the following:
CleanCache "true";
AutoCleanCache "true";
delHistory "1";

Its a bit of non-graphical tuning of the synaptic-app!
Cheers & thanks! *Thumbs up**Thumbs up*

Hi,

you can put the last 'sed' script in one line in the console and will make the changes you need. You just need to modify 'pattern/newpattern' accordingly to what you want. I said that it does not qualify as a one-liner just because I personally consider a sed statement as one liner if it does not exceed five commands.
If you add the -i.bak option you won't even have to redirect the output to a new file and it will also make a backup of the processed file.


All times are GMT -5. The time now is 04:41 PM.