我正在做这样的事情:
echo 'foo_bar_baz=foo_bar_baz' | sed -r 's/_([[:alnum:]])/U1/g'
并得到结果:
fooBarBaz=fooBarBaz
有没有办法获得fooBarBaz=foo_bar_baz
?
我试图这样做,不贪婪:
echo 'foo_bar_baz=foo_bar_baz' | sed -r 's/([^=].*?)_([[:alnum:]])/1U2/g'
但结果是这样的:
foo_bar_baz=foo_barBaz
我需要的是转换自:
foo_bar_baz=foo_bar_baz
自:
fooBarBaz=foo_bar_baz
编辑:
添加更多通用解决方案,该解决方案也适用于 3 个以上的值,然后再=
。
awk '
BEGIN{
FS=OFS="="
}
{
num=split($1,array,"_")
for(i=2;i<=num;i++){
val=(val?val:"")toupper(substr(array[i],1,1)) substr(array[i],2)
}
$1=array[1] val
val=""
}
1
' Input_file
这对awk
来说应该是一件容易的事。
echo 'foo_bar_baz=foo_bar_baz' | awk '
BEGIN{
FS=OFS="="
}
{
split($1,array,"_")
$1=array[1] toupper(substr(array[2],1,1)) substr(array[2],2) toupper(substr(array[3],1,1)) substr(array[3],2)
}
1'
要简单地删除第一部分使用中的_
(这不会使字母大写(:
echo 'foo_bar_baz=foo_bar_baz' | awk 'BEGIN{FS=OFS="="}{gsub(/_/,"",$1)} 1'
您可以使用
s='foo_bar_baz=foo_bar_baz'
sed -E ':a;s/^([^=_]*)_([[:alnum:]])/1U2/g; ta' <<< "$s"
# => fooBarBaz=foo_bar_baz
查看在线sed
演示
详
:a
- 定义替换成功时要跳转到的a
标签s/^([^=_]*)_([[:alnum:]])/1U2/g
- 查找^
- 字符串的开头([^=_]*)
- 组 1(替换模式中的1
(:除=
和_
以外的任何 0+ 字符_
- 下划线([[:alnum:]])
- 组 2(替换模式中的2
(:字母数字字符1U2
- 组 1 值,然后是大写的组 2 值
ta
-t
是一个分支命令,使 sed 返回到a
标签并重复匹配。
这可能对你有用(GNU sed(:
sed -E 'h;s/_(.)/u1/g;G;s/=.*=/=/' file
复制当前行。删除所有_
的字符,并将以下字符大写。附加副本并将=
之间的所有内容替换为单个=
。
另一种选择:
sed -E ':a;s/_(.*=)/u1/;ta' file
使用 GNU awk 用于第三个 arg 匹配((:
$ echo 'foo_bar_baz=foo_bar_baz' |
awk '{while (match($0,/(.*)_(.)(.*=.*)/,a)) $0 = a[1] toupper(a[2]) a[3]} 1'
fooBarBaz=foo_bar_baz
请注意,上述解决方案不限于任何特定数量的_
,也不限于下划线后的任何特定字母:
$ echo 'wee_sleekit_cowrin_timrous_beastie=foo_bar_baz' |
awk '{while (match($0,/(.*)_(.)(.*=.*)/,a)) $0 = a[1] toupper(a[2]) a[3]} 1'
weeSleekitCowrinTimrousBeastie=foo_bar_baz
如果只想删除后跟小写字母的下划线,请将_(.)
更改为_([[:lower:]])
。