sed包含可能包含斜杠的任意变量

时间:2014-02-11 05:01:09

标签: bash shell sed

我正在尝试以下列方式使用sed:

VAR=`echo $STRING | sed s/$TOKEN/$REPLACEMENT/`

不幸的是,我遇到了一个$ REPLACEMENT可能包含斜杠的情况。这导致bash抱怨,因为它(shell)可能会将它扩展为类似的东西:

#given $VAR=I like bananas, $TOKEN=bananas, and $REPLACEMENT=apples/oranges
VAR=`echo I like bananas | sed s/bananas/apples/oranges/`

所以现在sed被赋予了一个无效的参数太多了。有没有什么好方法可以解决这个问题?

3 个答案:

答案 0 :(得分:3)

您可以使用任何您喜欢的分隔符。 "s!$TOKEN!$REPLACEMENT!""s%$TOKEN%$REPLACEMENT%"是受欢迎的替代品。

当然,在一般情况下,如果输入可以包含任何字符,那么您将回到原点。您可以切换到一种不会混淆代码和数据的语言......实际上包括shell本身;

echo "${VAR/$TOKEN/$REPLACEMENT}"

(这是一个Bash扩展。它可以在其他一些shell中使用,但不能在经典的Bourne shell中使用。)

答案 1 :(得分:1)

这是修复

VAR="I like bananas"
TOKEN="bananas"
REPLACEMENT="apples/oranges"
echo $VAR |sed "s@$TOKEN@$REPLACEMENT@"

I like apples/oranges

答案 2 :(得分:0)

你无法可靠地将sed用作:

  1. 你通常找不到保证不会出现的角色 在任何$ TOKEN或$ REPLACEMENT字符串中,以及
  2. sed无法搜索字符串 - 它总是搜索正则表达式和 因此,$ TOKEN中的任何RE元字符都将被评估为您和您 无法可靠地实现代码来逃避它们(尽管有很多 人们已经尝试过。)
  3. 所以,只需使用awk:

    VAR=$(echo "$STRING" | awk -v t="$TOKEN" -v r="$REPLACEMENT" 'idx=index($0,t) {$0 = substr($0,1,idx-1) r substr($0,idx+length(t))} 1')
    

    除了$ STRING中的换行符之外,这将适用于3个字符串中的任何一个字符。

    如果没有echo,它也会处理$ STRING中的换行符:

    VAR=$(awk -v s="$STRING" -v t="$TOKEN" -v r="$REPLACEMENT" '
    BEGIN {
        if (idx = index(s,t))
            s = substr(s,1,idx-1) r substr(s,idx+length(t))
        print s
    }')