tags:

views:

157

answers:

3

Before overwriting I have copied /boot/grub/menu.lst to /home/san. I am running sed on the /home/san/menu.lst just for testing.

How can i overwrite

default 0

to

default 1

with the help of sed. I used following commands but none worked. It's most probably because i don't how many spaces are there in between "default" and "0". I thought there were two spaces and one tab but I was wrong.

sed -e 's/default  \t0/default  \t1/' /home/san/menu.lst
sed -e 's/default\t0/default\t1/' /home/san/menu.lst
sed -e 's/default \t0/default \t1/' /home/san/menu.lst
sed -e 's/default  0/default 1/' /home/san/menu.lst

I actually want to write a script that may see if 'default 0' is written in menu.lst then replace it with 'default 1' and if 'default 1' is written then replace it with 'default 2'.

Thanks

Update:

How can used a conditional statement to see if the line starting with 'default' has "0" or "1" written after it? If "0" replace with "1" and if "1" replace it with "0"?

+3  A: 

This works for me (with another file, of course ;)

sed -re 's/^default([ \t]+)0$/default\11/' /home/san/menu.lst

How it works:

  1. Passing -r to sed allows us to use extended regular expressions, thus no need to escape the parentheses and plus sign.
  2. [ \t]+ matches one or more tabs or spaces, in any order.
  3. Putting parentheses around this, that is ([ \t]+), turns this into a group, to which we can refer.
  4. This is the only group in this case, thus \1. That is what happens in the replacement string.
  5. We don't want to replace default 0 as part of a larger string. Thus we use ^ and $, which match the start and end of the line, respectively.

Note that:

  1. Using a group is not strictly necessary. You can also opt to replace all those tabs and spaces by a single tab or space. In that case just omit the parentheses and replace \1 with a space:

    sed -re 's/^default[ \t]+0$/default 1/' /home/san/menu.lst
    
  2. This will fail if there is trailing whitespace after default 0. If that is a concern, then you can match [ \t]* (zero or more tabs and spaces) just before the EOL:

    sed -re 's/^default([ \t]+)0[ \t]*$/default\11/' /home/san/menu.lst
    
Stephan202
Thanks man. :) Can you please tell what does 'default\11' mean?
baltusaj
Just updated the answer with an explanation :)
Stephan202
Awesome. Loved the 'group' thing.Thanks a lot. :)
baltusaj
Thanks for the note. Can you please see the post again. I have updated it with a new but related question when you get some free time?
baltusaj
You should really post that as a **separate** question.
Stephan202
+1  A: 

Firstly, you could use several lines like this:

 sed -re 's/default([ \t]*)0/default\11/' /home/san/menu.lst.

However, you might be better off with one line like this:

 awk '/^default/ { if ($2 == 1) print "default  0" ; else print "default 1" } !/^default/ {print}' /boot/grub/menu.lst
Shannon Nelson
Thanks Shannon. Is there a way with awk to see if its "1" in front of "default", then replace it with "0" or if its "0" then replace with "1". Or should i use IF-ELSE statement.
baltusaj
Here's an edit to make it a 1->0 0->1 switch.
Shannon Nelson
Thanks Shannon for helping me out.
baltusaj
+1  A: 

This substitutes 1 for 0, 0 for 1:

sed -r '/^default[ \t]+[01]$/{s/0/1/;t;s/1/0/}'

This substitutes 1 for 0, 2 for 1, 0 for 2:

sed -r '/^default[ \t]+[012]$/{s/0/1/;t;s/1/2/;t;s/2/0/}'

Briefly:

  • /^default[ \t]+[01]$/ uses addressing to select lines that consist only of "default 0" or "default 1" (or "default 2" in the second form) with any non-zero amount of spaces and/or tabs between "default" and the number
  • s/0/1/ - substitute a "1" for a "0"
  • t - branch to the end if a substitution was made, if not then continue with the next command
  • followed by more substitution(s) (and branches)

Edit:

Here's another way to do it:

sed -r '/^default[ \t]+[012]$/y/012/120/'
Dennis Williamson