Bash: Appending to existing values using sed capture group

sed is a powerful utility for transforming text.  One of the nice tricks with sed is the ability to reuse capture groups from the source string in the replacement value you are constructing.

For example, if you have have the following kernel parameters in “/etc/default/grub”

$ grep GRUB_CMDLINE_LINUX_DEFAULT /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

And wanted to append values to this line, you could put a capture group around the original value, and then use “\1” to represent the source capture group in the destination.

sed -ie 's/GRUB_CMDLINE_LINUX_DEFAULT="\(.*\)"/GRUB_CMDLINE_LINUX_DEFAULT="\1 cgroup_enable=memory swapaccount=1"/' /etc/default/grub

Which would result in the original plus our appended values.

$ grep GRUB_CMDLINE_LINUX_DEFAULT /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash cgroup_enable=memory swapaccount=1"

Take note of the need to escape the source parentheses with a backslash.

 

REFERENCES

sed man

NOTES

Proper escaping when done through yaml like cloud_init.cfg; single quotes doubled up and double quotes escaped with backslash.

runcmd:
  - [ sh, -c, 'sudo sed -ie ''s/^GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"cgroup_enable=memory swapaccount=1\"/'' /etc/default/grub' ]