将蛇形大小写转换为驼峰大小写,直到使用 sed 的特殊字符
convert snake case to camel case until a special character with sed
我正在尝试将 Localizable.strings 的密钥从 Mac 上的蛇形外壳转换为驼峰外壳。我可以使用 gsed,因为它支持 \U
大写。
我的文件如下所示:
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signup_email" = "Email";
/* recover_email */
"home.signup_email_recover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
我希望修改此文件以获得此:
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signupEmail" = "Email";
/* recover_email */
"home.signupEmailRecover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
我尝试将 gsed
与类似的东西一起使用,但不幸的是,我无法在 =
字符之后停止。
find . -name "*.strings" | xargs gsed -i -e '/=/! s/_\([a-z]\)/\U/gi'
知道如何在 =
之后停止替换 _
吗?
谢谢!
您可以使用
sed ':a;s/^\([^=]*\)_\([[:alpha:]]\)/\U\E/;ta'
如果您只想替换 _
+ 小写字母,您也可以使用 [[:lower:]]
而不是 [[:alpha:]]
。
详情:
:a
- 设置一个 a
标签
s/^\([^=]*\)_\([[:alpha:]]\)/\U\E/
- 找到除 =
字符以外的任何零个或多个字符并将其捕获到第 1 组中,然后匹配 _
然后将任何字母捕获到组中,然后替换第 1 组 + 第 1 组中的大写字母
ta
- 如果替换成功,则跳回到 a
标签位置。
参见 online demo:
#!/bin/bash
s='/* Title */
"home.title" = "Welcome";
/* Email */
"home.signup_email" = "Email";
/* recover_email */
"home.signup_email_recover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
/* One more string */
"my_string_key" = "[Click here](https://my.url.com/deeplink?id=UUID§ion_id=foo)";'
sed ':a;s/^\([^=]*\)_\([[:alpha:]]\)/\U\E/;ta' <<< "$s"
输出:
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signupEmail" = "Email";
/* recoverEmail */
"home.signupEmailRecover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
/* One more string */
"myStringKey" = "[Click here](https://my.url.com/deeplink?id=UUID§ion_id=foo)";
有点冗长,但这里有一个 non-regex 方法,使用 OSX 上可用的默认 BSD awk:
awk '
BEGIN {FS=OFS="="}
NF == 2 && (n = split(, a, /_/)) {
s = a[1]
for (i=2; i<=n; ++i)
s = s toupper(substr(a[i], 1, 1)) substr(a[i], 2)
= s
} 1' file
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signupEmail" = "Email";
/* recover_email */
"home.signupEmailRecover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
如果您不介意 gnu gawk
特定的解决方案:
# always true condition whether
# ORS contains empty string
#
gawk '(ORS=toupper(substr(RT,2)))~_' RS='_[a-z]' file
or
# +ORS is always 0/false,
# so !+ORS is always 1/ true
#
gawk '!+(ORS=toupper(substr(RT,2)))' RS='_[a-z]' file
or
gawk 'sub(/$/,toupper(substr(RT,2)))' ORS= RS='_[a-z]' file
or
# this just means
# 0-to-0th-power
#
gawk 'FS^(ORS=toupper(substr(RT,2)))' RS='_[a-z]' file
or
# ASCII string-compare that is always true since
# underscore "_" has higher byte ordinance than
# either empty string or any ASCII uppercase letters
#
gawk '(ORS=toupper(substr(RT,2)))<RS' RS='_[a-z]' file
=
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signupEmail" = "Email";
/* recoverEmail */
"home.signupEmailRecover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
我正在尝试将 Localizable.strings 的密钥从 Mac 上的蛇形外壳转换为驼峰外壳。我可以使用 gsed,因为它支持 \U
大写。
我的文件如下所示:
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signup_email" = "Email";
/* recover_email */
"home.signup_email_recover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
我希望修改此文件以获得此:
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signupEmail" = "Email";
/* recover_email */
"home.signupEmailRecover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
我尝试将 gsed
与类似的东西一起使用,但不幸的是,我无法在 =
字符之后停止。
find . -name "*.strings" | xargs gsed -i -e '/=/! s/_\([a-z]\)/\U/gi'
知道如何在 =
之后停止替换 _
吗?
谢谢!
您可以使用
sed ':a;s/^\([^=]*\)_\([[:alpha:]]\)/\U\E/;ta'
如果您只想替换 _
+ 小写字母,您也可以使用 [[:lower:]]
而不是 [[:alpha:]]
。
详情:
:a
- 设置一个a
标签s/^\([^=]*\)_\([[:alpha:]]\)/\U\E/
- 找到除=
字符以外的任何零个或多个字符并将其捕获到第 1 组中,然后匹配_
然后将任何字母捕获到组中,然后替换第 1 组 + 第 1 组中的大写字母ta
- 如果替换成功,则跳回到a
标签位置。
参见 online demo:
#!/bin/bash
s='/* Title */
"home.title" = "Welcome";
/* Email */
"home.signup_email" = "Email";
/* recover_email */
"home.signup_email_recover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
/* One more string */
"my_string_key" = "[Click here](https://my.url.com/deeplink?id=UUID§ion_id=foo)";'
sed ':a;s/^\([^=]*\)_\([[:alpha:]]\)/\U\E/;ta' <<< "$s"
输出:
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signupEmail" = "Email";
/* recoverEmail */
"home.signupEmailRecover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
/* One more string */
"myStringKey" = "[Click here](https://my.url.com/deeplink?id=UUID§ion_id=foo)";
有点冗长,但这里有一个 non-regex 方法,使用 OSX 上可用的默认 BSD awk:
awk '
BEGIN {FS=OFS="="}
NF == 2 && (n = split(, a, /_/)) {
s = a[1]
for (i=2; i<=n; ++i)
s = s toupper(substr(a[i], 1, 1)) substr(a[i], 2)
= s
} 1' file
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signupEmail" = "Email";
/* recover_email */
"home.signupEmailRecover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";
如果您不介意 gnu gawk
特定的解决方案:
# always true condition whether
# ORS contains empty string
#
gawk '(ORS=toupper(substr(RT,2)))~_' RS='_[a-z]' file
or
# +ORS is always 0/false,
# so !+ORS is always 1/ true
#
gawk '!+(ORS=toupper(substr(RT,2)))' RS='_[a-z]' file
or
gawk 'sub(/$/,toupper(substr(RT,2)))' ORS= RS='_[a-z]' file
or
# this just means
# 0-to-0th-power
#
gawk 'FS^(ORS=toupper(substr(RT,2)))' RS='_[a-z]' file
or
# ASCII string-compare that is always true since
# underscore "_" has higher byte ordinance than
# either empty string or any ASCII uppercase letters
#
gawk '(ORS=toupper(substr(RT,2)))<RS' RS='_[a-z]' file
=
/* Title */
"home.title" = "Welcome";
/* Email */
"home.signupEmail" = "Email";
/* recoverEmail */
"home.signupEmailRecover" = "Recover Email";
/* password */
"home.password" = "Enter your __Password__:";