【问题标题】:Bash script: find and replace uppercase character on a stringBash脚本:查找和替换字符串上的大写字符
【发布时间】:2016-01-23 02:59:30
【问题描述】:

假设我们有这样的字符串:

doSomething()

我们想要获得:

do_something()

最好的方法是什么?
我已阅读documentation 关于字符串操作,但我找不到正确的命令组合..

更新

@anubhava 讨论后,我找到了安装 gnu-sed 的解决方案:

brew install gnu-sed

然后我可以这样运行脚本:

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

输出: do_something_else()

【问题讨论】:

  • 我一直在尝试使用 Bash 4 case 修改 parameter expansion 来做到这一点,但到目前为止都失败了。 (我预计至少需要两次不同的扩展。)我想知道是否可以只使用 PE 和重新分配。

标签: string macos bash replace terminal


【解决方案1】:

使用gnu-sed 你可以做到:

s='doSomethingElse()'

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

否则non-gnu-sed (BSD) 管道和tr

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

或者使用perl:

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

或者使用gnu-awk:

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

【讨论】:

  • 我在mac下使用iTerm(而且awk也不适合我)
  • ITerm 只是一个终端。默认情况下,OSX 不附带 gnu 实用程序。在我的 OSX(我测试了两个命令)上,我使用 home brew 安装了 gnu-sed 和 gnu-awk。
  • 好的,但在这种情况下,其他用户必须安装“gnu-sed”才能正确运行脚本
  • 在 OSX sed 你可以使用sed 's/[[:upper:]]/_&amp;/g' &lt;&lt;&lt; "$s" | tr [[:upper:]] [[:lower:]]
  • 非常感谢阿维纳什 :)
【解决方案2】:

bash 4:

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

首先,while 循环尝试匹配紧随其后的大写字符的小写字符,并捕获匹配的大写字符。参数扩展将字符串中的第一个大写字符替换为下划线和捕获的大写字符(由,, 运算符转换为小写)。重复该过程,直到找不到更多的较低/较高对。


如果bash 允许按模式捕获组,那么假设是这样的

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

可以在没有循环的情况下工作。照原样,我们需要使用正则表达式一次匹配一个匹配项的额外步骤来捕获要小写的字母。

【讨论】:

    猜你喜欢
    • 2014-02-17
    • 1970-01-01
    • 2019-11-03
    • 2022-07-21
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 2017-03-10
    • 2021-03-07
    相关资源
    最近更新 更多