0

I'm trying to use sed in a script to modify a line in my grub configuration file(/boot/grub/grub.cfg) each time grub updates. I wish to replace the following line:

menuentry "Kali GNU/Linux"

with this:

'menuentry "Kali GNU/Linux" --class kali'

The line in /boot/grub/grub.cfg is as follows:

menuentry "Kali GNU/Linux" --class gnu-linux --class os $menuentry_id_option 'osprober-gnulinux-/boot/vmlinuz-5.14.0-kali2-amd64--7afb9c25-9d47-4ce4-a3dd-635aa0b04d7a'

Basically, what I want to do is add the line --class kali. I cannot replace gnu-linux or os with kali as those words occur multiple times.

The script I've used is as follows:

TARGET_STRING='menuentry "Kali GNU/Linux"'
NEW_STRING='menuentry "Kali GNU/Linux" --class kali'
sudo sed -i "s/$TARGET_STRING/$NEW_STRING/g" /boot/grub/grub.cfg

This fails to work, giving the following error:

sed: -e expression #1, char 32: unknown option to `s'

I've found solutions online for substituting a string containing spaces here and substituting a string containing double quotes here, but not when a string contains both.

Could someone please help me out?

Note: I am using GNU sed 4.7

4
  • 1
    Relating unix.stackexchange.com/questions/32907/… (your replacement string contains a /, confusing sed)
    – Jeff Schaller
    Commented Nov 16, 2021 at 13:25
  • try specifying another request separator like sudo sed -i "s@$TARGET_STRING@$NEW_STRING@g" /boot/grub/grub.cfg it is less error sources on special characters & characters that are used in the sed request syntax.
    – francois P
    Commented Nov 16, 2021 at 13:36
  • @francoisP (and Jeff Schaller :) ) please don't post answers in the comment section; rather, write them up as dedicated answer (unless you know a question that this one is a duplicate of, in which case please vote to close this one as duplicate).
    – AdminBee
    Commented Nov 16, 2021 at 13:55
  • I hesitate to cast close votes unless it's very clear-cut, since I have a binding vote; the Q/A I linked to was a general one, but it can be worked around in other ways, as terdon has shown.
    – Jeff Schaller
    Commented Nov 16, 2021 at 16:24

1 Answer 1

3

There is no need for variables. Just use the strings directly:

sudo sed -i 's|menuentry "Kali GNU/Linux"|menuentry "Kali GNU/Linux" --class kali|' /boot/grub/grub.cfg

You are getting the errors because your strings contain / and you were using / as the separator in the s/// operator. You can use any character for that though, which is why I am using s||| above. In general, you need to be sure to pick a character that is not present in either the $target_string or the $new_string. So | works in this example, but you might need to pick another one for other cases.

You can use variables if you really, really want to, they're just not helping here. Also, as a general rule, it is better to avoid CAPITAL variable names in shell scripts. This would work though:

target_string='menuentry "Kali GNU/Linux"'
new_string='menuentry "Kali GNU/Linux" --class kali'
sudo sed -i "s|$target_string|$new_string|" /boot/grub/grub.cfg
2
  • Using the strings directly gave the error sed: -e expression #1, char 16: unterminated s' command`. The script using variables worked though. Thanks a lot.
    – Gagan
    Commented Nov 17, 2021 at 0:31
  • @Gagan eek! That's because I was using " by mistake instead of '. Try the updated answer, both approaches should work now.
    – terdon
    Commented Nov 17, 2021 at 9:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .