sed替换使用shell变量

时间:2016-06-06 13:27:03

标签: bash shell sed

我在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

2 个答案:

答案 0 :(得分:1)

我可以通过确保$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分别修剪与下列模式匹配的最长前缀或后缀。就其本身而言,模式匹配任何正数空白字符的字符串。

答案 1 :(得分:0)

使用您的代码,我在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-RELEASE)。我不知道为什么,并且无法找到解释这与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部分保留在简单的引号中,并将变量放在双引号之间)。