Linux sed 表达式将驼峰式键转换为下划线字符串
Linux sed expression to convert the camelCase keys to underscore strings
我无法让正则表达式仅将键值对中的键从驼峰式大小写转换为下划线字符串。
像sed -E 's/\B[A-Z]/_\U&/g'这样的表达式转换了完整的值,但我想在这里只转换到键。
$ echo UserPoolId="eu-west-1_6K6Q2bT9c" | sed -E 's/\B[A-Z]/_\U&/g'
User_Pool_Id=eu-west-1_6_K6_Q2b_T9c
但我想得到 User_Pool_Id=eu-west-1_6K6Q2bT9c
在 sed
中执行此操作有些挑战性,因为您需要更复杂的正则表达式和更复杂的脚本。也许更好的解决方案是使用 shell 的替代设施来隔离您要操作的部分。
string='UserPoolId="eu-west-1_6K6Q2bT9c"'
prefix=${string%%=*}
suffix=${string#"$prefix"}
sed -E -e 's/\B[A-Z]/_\U&/g' -e "s/$/$suffix/" <<<"$prefix"
Bash 也有 built-in parameter expansion 将字符串的第一个字符转换为大写,但这也许足以解决您眼前的问题。
这可能适合您 (GNU sed):
sed 's/=/&\n/;h;s/\B[[:upper:]]/_&/g;G;s/\n.*\n//' file
在=
之后换行,将结果复制到space.
在需要的地方插入下划线。
将副本追加到当前行并删除中间部分,留下答案。
使用 GNU awk 将第 3 个参数匹配 () 和 gensub():
$ echo 'UserPoolId="eu-west-1_6K6Q2bT9c"' |
awk 'match([=10=],/([^=]+=)"(.*)"/,a) { [=10=]=gensub(/([[:lower:]])([[:upper:]])/,"\1_\2","g",a[1]) a[2]} 1'
User_Pool_Id=eu-west-1_6K6Q2bT9c
我不知道这是否是您想要的,但无论如何:
$ echo 'UserPoolID="eu-west-1_6K6Q2bT9c"' |
awk 'match([=11=],/([^=]+=)"(.*)"/,a) { [=11=]=gensub(/([[:lower:]])([[:upper:]])/,"\1_\2","g",a[1]) a[2]} 1'
User_Pool_ID=eu-west-1_6K6Q2bT9c
请注意,ID
保持为 _ID
,不会转换为 _I_D
。
如果你只有一个 =
符号并且你想修改 =
符号之前的驼峰式大小写,使用 GNU sed
你可以迭代直到所有替换完成:
echo UserPoolId="eu-west-1_6K6Q2bT9c" | sed -E ':a;s/([a-z])([A-Z].*=.*)/_/;ta'
User_Pool_Id=eu-west-1_6K6Q2bT9c
:a
设置标签 a
,如果之前的 s
命令替换了某些内容,ta
分支到标签 a
。循环中的 s
命令在 等号 之前的小写和大写 之间插入一个 _
。
在您的示例中,这将首先在 User
和 Pool
之间插入一个 _
,然后在 Pool
和 Id
之间插入一个 _
。
我无法让正则表达式仅将键值对中的键从驼峰式大小写转换为下划线字符串。
像sed -E 's/\B[A-Z]/_\U&/g'这样的表达式转换了完整的值,但我想在这里只转换到键。
$ echo UserPoolId="eu-west-1_6K6Q2bT9c" | sed -E 's/\B[A-Z]/_\U&/g'
User_Pool_Id=eu-west-1_6_K6_Q2b_T9c
但我想得到 User_Pool_Id=eu-west-1_6K6Q2bT9c
在 sed
中执行此操作有些挑战性,因为您需要更复杂的正则表达式和更复杂的脚本。也许更好的解决方案是使用 shell 的替代设施来隔离您要操作的部分。
string='UserPoolId="eu-west-1_6K6Q2bT9c"'
prefix=${string%%=*}
suffix=${string#"$prefix"}
sed -E -e 's/\B[A-Z]/_\U&/g' -e "s/$/$suffix/" <<<"$prefix"
Bash 也有 built-in parameter expansion 将字符串的第一个字符转换为大写,但这也许足以解决您眼前的问题。
这可能适合您 (GNU sed):
sed 's/=/&\n/;h;s/\B[[:upper:]]/_&/g;G;s/\n.*\n//' file
在=
之后换行,将结果复制到space.
在需要的地方插入下划线。
将副本追加到当前行并删除中间部分,留下答案。
使用 GNU awk 将第 3 个参数匹配 () 和 gensub():
$ echo 'UserPoolId="eu-west-1_6K6Q2bT9c"' |
awk 'match([=10=],/([^=]+=)"(.*)"/,a) { [=10=]=gensub(/([[:lower:]])([[:upper:]])/,"\1_\2","g",a[1]) a[2]} 1'
User_Pool_Id=eu-west-1_6K6Q2bT9c
我不知道这是否是您想要的,但无论如何:
$ echo 'UserPoolID="eu-west-1_6K6Q2bT9c"' |
awk 'match([=11=],/([^=]+=)"(.*)"/,a) { [=11=]=gensub(/([[:lower:]])([[:upper:]])/,"\1_\2","g",a[1]) a[2]} 1'
User_Pool_ID=eu-west-1_6K6Q2bT9c
请注意,ID
保持为 _ID
,不会转换为 _I_D
。
如果你只有一个 =
符号并且你想修改 =
符号之前的驼峰式大小写,使用 GNU sed
你可以迭代直到所有替换完成:
echo UserPoolId="eu-west-1_6K6Q2bT9c" | sed -E ':a;s/([a-z])([A-Z].*=.*)/_/;ta'
User_Pool_Id=eu-west-1_6K6Q2bT9c
:a
设置标签 a
,如果之前的 s
命令替换了某些内容,ta
分支到标签 a
。循环中的 s
命令在 等号 之前的小写和大写 之间插入一个 _
。
在您的示例中,这将首先在 User
和 Pool
之间插入一个 _
,然后在 Pool
和 Id
之间插入一个 _
。