mikeb mikeb - 1 year ago 55
Bash Question

sed replace using shell variables

I'm on Linux Mint 17

I got this command looking at other sed questions on here, but can't seem to get it to work. Can anyone suggest what is wrong here? This seems pretty simple but won't work:

$ cat t | sed "s/${FSTAB_UUID}/${SWAP_UUID}/"

sed: -e expression #1, char 2: unterminated `s' command

$ echo $FSTAB_UUID


$ echo $SWAP_UUID


$ cat t

UUID=accbd859-7cdd-4d00-86ea-2b5d7d1cee75 / ext4 errors=remount-ro 0 1
UUID=15542fac-468c-405f-a156-dd781ece7568 none swap rw 0 0

Answer Source

I can reproduce your problem by ensuring that the value of $FSTAB_UUID starts with a newline (as suggested by @StefanHegny):

> 15542fac-468c-405f-a156-dd781ece7568"
$ echo $FSTAB_UUID
$ echo ">>>$FSTAB_UUID<<<"
$ sed "s/${FSTAB_UUID}/${SWAP_UUID}/" t
sed: -e expression #1, char 2: unterminated `s' command

(Note that the leading > on the second line is a secondary prompt emitted by bash; it is not part of the input.) I see no other explanation for the behavior.

The best solution is to set the values for $FSTAB_UUID and $SWAP_UUID in a way that does not introduce leading or trailing newlines. I can't be any more specific, because it's unclear how they are getting in in the first place.

If you can't keep the newlines out, then you also have the option of taking them out after the fact. This is a bit ugly, but it will remove all leading and trailing whitespace, including newlines, from both values:


The ## and %% inside the parameter expansions tell bash to trim the longest prefix or suffix, respectively, that matches the following pattern. For its part, the pattern matches a string of any positive number of whitespace characters.