简体   繁体   English

Bash脚本:查找并替换字符串上的大写字符

[英]Bash script: find and replace uppercase character on a string

Saying we have a string like: 说我们有一个像这样的字符串:

doSomething()

and we want to obtain: 我们希望获得:

do_something()

What is the best way to do this? 做这个的最好方式是什么?
I've read documentation about strings manipulation but I can't find the right command combination.. 我已经阅读了有关字符串操作的 文档 ,但我找不到正确的命令组合..

update 更新

After @anubhava discussion, I find solution installing gnu-sed: 在@anubhava讨论之后,我找到安装gnu-sed的解决方案:

brew install gnu-sed

And then I can run script in this way: 然后我可以用这种方式运行脚本:

s="doSomethingElse()"; gsed 's/[[:upper:]]/_\L&/g' <<< "$s"

output: do_something_else() 输出: do_something_else()

Using gnu-sed you can do: 使用gnu-sed你可以这样做:

s='doSomethingElse()'

sed 's/[[:upper:]]/_\L&/g' <<< "$s"
do_something_else()

Or else with non-gnu-sed (BSD) pipe with tr : 或者使用带有tr non-gnu-sed (BSD)管道:

sed 's/[[:upper:]]/_&/g' <<< "$s" | tr [[:upper:]] [[:lower:]]
do_something_else()

Or using perl : 或使用perl

perl -pe 's/[[:upper:]]/_\L$&/g' <<< "$s"
do_something_else()

Or using gnu-awk : 或者使用gnu-awk

awk -v RS=[[:upper:]] -v ORS= '1; RT{printf "_%s", tolower(RT)}' <<< "$s"
do_something_else()

In bash 4: bash 4中:

$ s="doSomethingElse()"
$ while [[ $s =~ [[:lower:]]([[:upper:]]) ]]; do   
>     s=${s/[[:upper:]]/_${BASH_REMATCH[1],,}}
> done
$ echo "$s"
do_something_else()

First, the while loop tries to match a lowercase character immediately followed by an uppercase character, and capturing the matched uppercase character. 首先,while循环尝试匹配紧跟在大写字符后面的小写字符,并捕获匹配的大写字符。 The parameter expansion replaces the first uppercase character in the string with an underscore and the captured uppercase character (converted to lowercase by the ,, operator). 参数扩展使用下划线和捕获的大写字符替换字符串中的第一个大写字符(由,,运算符转换为小写)。 The processes repeats until no more lower/upper pairs are found. 重复这些过程直到找不到更多的上/下对。


If bash allowed capture groups in patterns, something hypothetical like 如果bash允许模式中的捕获组,那么假设就像

s=${s//([[:lower:]])([[:upper:]])/${BASH_PATMATCH[1]}_${BASH_PATMATCH[2],,}}

could work without a loop. 可以没有循环工作。 As is, we need the extra step of using regular expression matches one match at a time to capture the letter to be lowercased. 因此,我们需要使用正则表达式的额外步骤一次匹配一个匹配以捕获要小写的字母。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM