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

terdon
  • 242,166
Gagan
  • 660
  • 1
    Relating https://unix.stackexchange.com/questions/32907/what-characters-do-i-need-to-escape-when-using-sed-in-a-sh-script (your replacement string contains a /, confusing sed) – Jeff Schaller Nov 16 '21 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 Nov 16 '21 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 Nov 16 '21 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 Nov 16 '21 at 16:24

1 Answers1

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
terdon
  • 242,166
  • Using the strings directly gave the error sed: -e expression #1, char 16: unterminateds' command`. The script using variables worked though. Thanks a lot. – Gagan Nov 17 '21 at 00:31
  • @Gagan eek! That's because I was using " by mistake instead of '. Try the updated answer, both approaches should work now. – terdon Nov 17 '21 at 09:17