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]