sed使用shell变量替换



我在Linux Mint 17 上

我通过查看其他sed问题得到了这个命令,但似乎无法使其发挥作用。有人能指出这里出了什么问题吗?这看起来很简单,但不会起作用:

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

sed:-e表达式#1,字符2:未终止的"s"命令

$ echo $FSTAB_UUID

15542fac-468c-405f-a156-dd781ece7568

$ echo $SWAP_UUID

2891fb61-26c3-4606-b310-6c12e4788db5

$ 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

我可以通过确保$FSTAB_UUID的值以换行符开始来重现您的问题(如@StefanHegny所建议的):

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

(请注意,第二行的前导>bash发出的辅助提示;它不是输入的一部分。)我看不到对该行为的其他解释。

最好的解决方案是以不引入前导或尾随换行的方式设置$FSTAB_UUID$SWAP_UUID的值。我不能再具体了,因为他们一开始是如何进入的还不清楚。

如果你不能保留换行符,那么你也可以选择在事后删除它们。这有点难看,但它将从两个值中删除所有前导和尾部空白,包括换行符:

FSTAB_UUID=${FSTAB_UUID##+([[:space:]])}
FSTAB_UUID=${FSTAB_UUID%%+([[:space:]])}
SWAP_UUID=${SWAP_UUID##+([[:space:]])}
SWAP_UUID=${SWAP_UUID%%+([[:space:]])}

参数展开中的##%%告诉bash分别修剪与以下模式匹配的最长前缀或后缀。就其本身而言,该模式匹配由任意正数的空白字符组成的字符串。

使用您的代码,我在Linux上得到了一个类似的(唯一的)错误(bash 4.3.11 GNU sed 4.2.2):

$ FSTAB_UUID=15542fac-468c-405f-a156-dd781ece7568
$ SWAP_UUID=2891fb61-26c3-4606-b310-6c12e4788db5
$ cat t |  sed "s/${FSTAB_UUID}/${SWAP_UUID}/"
sed: -e expression n°1, caractère 0: pas d'expression régulière précédente

(翻译:sed:-e表达式#1,字符0:没有以前的正则表达式)

但在FreeBSD(10.2-RELESE)上没有。我不知道为什么,也找不到任何解释GNU sed和经典sed之间区别的东西。

现在,在我的Linux盒子上,虽然这可能不是最漂亮的解决方法,尽管的行为不应该与您的代码不同,但这仍然可以得到预期的结果:

$ cat t |  sed 's/'"${FSTAB_UUID}"'/'"${SWAP_UUID}"'/'
UUID=accbd859-7cdd-4d00-86ea-2b5d7d1cee75 /     ext4  errors=remount-ro 0 1
UUID=2891fb61-26c3-4606-b310-6c12e4788db5 none  swap  rw 0 0
$ 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
$ 

(只需将sed部分放在单引号中,并将变量放在双引号之间)。

相关内容

  • 没有找到相关文章