linuxbashsedrhel

sed + append text at end of a specific line but before specific character


I want to add the text scsi_mod.scan=sync on the end of the line that start with GRUB_CMDLINE_LINUX and append the text at the end of the line but before the character ".

In case scsi_mod.scan=sync already exist then sed should not append an additional scsi_mod.scan=sync.

We did the following

sed -i '/GRUB_CMDLINE_LINUX/s/$/ scsi_mod.scan=sync/' /etc/default/grub

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=VG/LV_root rd.lvm.lv=VG/lv_swap ipv6.disable=1 rhgb quiet scsi_mod.scan=sync" scsi_mod.scan=sync
GRUB_DISABLE_RECOVERY="true"

but as you can see from the example above, we not succeeded to append the text before ".

The expected results should be like this

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=VG/LV_root rd.lvm.lv=VG/lv_swap ipv6.disable=1 rhgb quiet scsi_mod.scan=sync" 
GRUB_DISABLE_RECOVERY="true"

Solution

  • With GNU sed you can try:

    sed -i '/GRUB_CMDLINE_LINUX/{/\<scsi_mod.scan=sync"$/!s/"$/ scsi_mod.scan=sync"/}' /etc/default/grub
    

    If you want to skip the additio if scsi_mod.scan=sync is anywhere in the line, not only at the end:

    sed -i '/GRUB_CMDLINE_LINUX/{/\<scsi_mod.scan=sync\>/!s/"$/ scsi_mod.scan=sync"/}' /etc/default/grub