使用POSIX Shell将CamelCase转换为lowerCamelCase

6

我会尝试使用 Shell 脚本仅将字符串的第一个字母转换为小写。理想情况下,从 CamelCase 转换为 lowerCamelCase 的简单方法。

目标:

$DIR="SomeString"
# missing step
$echo $DIR
someString

我已经找到了一些非常好的资源,可以将整个字符串转换为小写,但并没有只改变第一个字母并保留其余字符串不变的方法。


@jaypalsingh 进行了编辑,感谢您的建议。 - haysclark
6个回答

6
如果您的shell版本足够新,您可以使用以下参数扩展:
DIR="SomeString"   # Note the missing dollar sign.
echo ${DIR,}

我正在使用OSX,看起来默认的Bash版本不是很新。当我尝试使用Bash v4功能时,会出现错误:bash: ${DIR,}: bad substitution - haysclark
请花点时间查看macports.org。除了OSX的BSD工具,您还可以获得许多优秀的GNU工具。 - clt60
@jm666 谢谢 :D 我很清楚 MacPorts 和 Brew。这是为了一个需要在各种平台上运行的构建脚本,它不属于我们使用 Rake 的主要构建脚本之外。 - haysclark

4

备选方案(也适用于旧版bash)

DIR="SomeString"
echo $(echo ${DIR:0:1} | tr "[A-Z]" "[a-z]")${DIR:1}

打印
someString

赋值给变量

DIR2="$(echo ${DIR:0:1} | tr "[A-Z]" "[a-z]")${DIR:1}"
echo $DIR2

打印

someString

替代 Perl
DIR3=$(echo SomeString | perl -ple 's/(.)/\l$1/')
DIR3=$(echo SomeString | perl -nle 'print lcfirst')
DIR3=$(echo "$DIR"     | perl -ple 's/.*/lcfirst/e'

一些糟糕的解决方案;

DIR4=$(echo "$DIR" | sed 's/^\(.\).*/\1/' | tr "[A-Z]" "[a-z]")$(echo "$DIR" | sed 's/^.//')
DIR5=$(echo "$DIR" | cut -c1 | tr '[[:upper:]]' '[[:lower:]]')$(echo "$DIR" | cut -c2-)

以上所有内容都是在OSX的/bin/bash下测试的。


首选使用 tr [[:upper:]] [[:lower:]],但对于BASH来说也是一个好的解决方案。 - David W.
只是让原帖作者知道,在 Mac 上的 BASH 中,这个版本号是 3.2,这个可以工作。 - David W.

3
使用sed命令:
var="SomeString"
echo $var | sed 's/^./\L&/'

^ 表示行首。 \L 是将匹配内容转换为小写的命令。 & 是完整的匹配结果。


感谢您提供的快速解决方案,不幸的是我正在使用POSIX sed,因此无法访问\L。 - haysclark
请查看您的 sed 手册和 re_format 手册。有时,如果在 sed 中使用 -E,它将使用 _扩展正则表达式_,其中可能包括 \L。您还可以看到其他可以传递给 sed 的参数,以扩展其正则表达式能力。 - David W.
如果您使用Homebrew,实际上可以在Mac上执行此操作:https://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools-in-mac-os-x/ - spinlock

2

既然还没有提到awk,那么这里有另一种方法可以实现(需要使用GNU awk):

dir="SomeString"
new_dir=$(awk 'BEGIN{FS=OFS=""}{$1=tolower($1)}1' <<<"$dir")

这将输入和输出字段分隔符设置为空字符串,因此每个字符都是一个字段。 tolower 函数执行其字面意思。末尾的1打印该行。如果您的shell不支持<<<,则可以改为使用echo "$dir" | awk ...


2

Perl解决方案:

DIR=SomeString
perl -le 'print lcfirst shift' "$DIR"

-1

如果您正在寻找符合POSIX标准的解决方案,请查看typeset

var='SomeString'
typeset -lL1 b="$var"
echo "${b}${var#?}"

输出:

someString

typeset 命令创建一个特殊的变量,它是小写的、左对齐的,并且只有一个字符长。${var#?}$var 的开头修剪第一次出现的模式,其中 ? 匹配单个字符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接