2011-04-11 53 views
8

如何在BASH中的替换表达式中包含正则表达式匹配?如何在bash中引用捕获正则表达式替换

非工作示例:

#!/bin/bash 
name=joshua 
echo ${name//[oa]/X\1} 

我希望输出jXoshuXa\1由匹配的字符被替换。

虽然这并不实际工作,但输出jX1shuX1

+2

我在我的bash(4.1.5)版本中看不到任何关于能够使用'$ {foo/bar/baz}'语法来执行正则表达式替换的内容。你有什么参考资料为什么你认为你应该能够做到这一点? – 2011-04-11 17:20:05

+0

我不知道我在哪里偶然发现它,但它确实有效。使用上面的示例,您可以看到它正在用'X'替换'o'和'a'。很漂亮。 – joshuapoehls 2011-04-11 17:29:58

+0

参见http://tldp.org/LDP/abs/html/parameter-substitution.html,对此的描述大概是页面下方的3/4。 – 2011-04-11 17:31:59

回答

7
bash> name=joshua 
bash> echo $name | sed 's/\([oa]\)/X\1/g' 
jXoshuXa 
+0

如果你打算达到sed,这很简单:'s/[oa]/X&/ g' – 2011-04-11 17:25:52

+0

谢谢!我希望能够在不调用'sed'的情况下做到这一点,但这也应该是一样的。 – joshuapoehls 2011-04-11 17:32:11

22

也许并不那么直观,可以说是模糊的,因为所有的地狱,但在完整的精神,在我们等待BASH捕捉替代到达,以下是目前可能的。

#!/bin/bash 
name='joshua' 
[[ $name =~ ([ao].*)([oa]) ]] && \ 
    echo ${name/$BASH_REMATCH/X${BASH_REMATCH[1]}X${BASH_REMATCH[2]}} 

在那个例子中,我们知道我们在找什么。接近匹配全部或全局正则表达式对应的下面的例子将贪婪地匹配到没有前缀X的集合的最后一次出现,并且继续向后直到没有剩余。

#/bin/bash 
name='joshua' 
while [[ $name =~ .*[^X]([oa]) ]]; do 
    name=${name/$BASH_REMATCH/${BASH_REMATCH:0:-1}X${BASH_REMATCH[1]}} 
done 
echo $name 

这个例子的工作方式与落后表达/(?<!X)([oa])/X\1/的目光假设只关心O和不具有前缀一个X一个字符。

输出两个例子

jXoshuXa 

的nJoy!