search并使用正则expression式在bash中进行replace

我见过这个例子:

hello=ho02123ware38384you443d34o3434ingtod38384day echo ${hello//[0-9]/} 

它遵循以下语法: ${variable//pattern/replacement}

不幸的是, pattern字段似乎不支持完整的正则expression式语法(如果我使用.\s ,例如,它试图匹配文字字符)。

我如何使用完整的正则expression式来search/replacestring?

使用sed :

 MYVAR=ho02123ware38384you443d34o3434ingtod38384day echo $MYVAR | sed -e 's/[a-zA-Z]/X/g' -e 's/[0-9]/N/g' # prints XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX 

请注意,随后的-e按顺序处理。 此外,expression式的g标志将匹配input中的所有事件。

你也可以用这个方法select你喜欢的工具,比如perl,awk,例如:

 echo $MYVAR | perl -pe 's/[a-zA-Z]/X/g and s/[0-9]/N/g' 

这可能会让你做更多的创意匹配……例如,在上面的剪辑中,除非第一个expression式匹配(由于懒惰and评估),否则不会使用数字replace。 当然,你有Perl的全部语言支持来做你的出价…

这实际上可以在纯粹的bash中完成:

 hello=ho02123ware38384you443d34o3434ingtod38384day re='(.*)[0-9]+(.*)' while [[ $hello =~ $re ]]; do hello=${BASH_REMATCH[1]}${BASH_REMATCH[2]} done echo "$hello" 

… …产量

 howareyoudoingtodday 

这些例子也可以在bash中使用,不需要使用sed:

 #!/bin/bash MYVAR=ho02123ware38384you443d34o3434ingtod38384day MYVAR=${MYVAR//[a-zA-Z]/X} echo ${MYVAR//[0-9]/N} 

您还可以使用字符类括号expression式

 #!/bin/bash MYVAR=ho02123ware38384you443d34o3434ingtod38384day MYVAR=${MYVAR//[[:alpha:]]/X} echo ${MYVAR//[[:digit:]]/N} 

产量

 XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX 

不过@Lanaru想知道的是,如果我正确地理解了这个问题,为什么“完整”或PCRE扩展\s\S\w\W\d\D等不能在php ruby​​ python等支持下工作。扩展名来自Perl兼容的正则expression式(PCRE),可能与其他forms的基于shell的正则expression式不兼容。

这些不起作用:

 #!/bin/bash hello=ho02123ware38384you443d34o3434ingtod38384day echo ${hello//\d/} #!/bin/bash hello=ho02123ware38384you443d34o3434ingtod38384day echo $hello | sed 's/\d//g' 

输出时删除了所有文字“d”字符

 ho02123ware38384you44334o3434ingto38384ay 

但下面的工作如预期

 #!/bin/bash hello=ho02123ware38384you443d34o3434ingtod38384day echo $hello | perl -pe 's/\d//g' 

产量

 howareyoudoingtodday 

希望澄清事情多一点,但如果你不困惑,为什么不尝试这个在启用了REG_ENHANCED标志的Mac OS X上:

 #!/bin/bash MYVAR=ho02123ware38384you443d34o3434ingtod38384day; echo $MYVAR | grep -o -E '\d' 

在大多数* nix的版本中,您只会看到以下输出:

 d d d 

的nJoy!

使用[[:digit:]] (注意双括号)作为模式:

 $ hello=ho02123ware38384you443d34o3434ingtod38384day $ echo ${hello//[[:digit:]]/} howareyoudoingtodday 

只是想总结答案(特别是@ nickl-的https://stackoverflow.com/a/22261334/2916086 )。

如果您正在重复调用并关注性能,则此testing显示BASH方法比分叉和可能的任何其他外部进程快大约15倍。

 hello=123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X P1=$(date +%s) for i in {1..10000} do echo $hello | sed s/X//g > /dev/null done P2=$(date +%s) echo $[$P2-$P1] for i in {1..10000} do echo ${hello//X/} > /dev/null done P3=$(date +%s) echo $[$P3-$P2]