Friday, July 29, 2022

[SOLVED] convert snake case to camel case until a special character with sed

Issue

I'm trying to convert the keys of Localizable.strings from snake case to camel case on a Mac. I can use gsed since it supports \U for uppercase.

My files looks like this:

/* Title  */
"home.title" = "Welcome";

/* Email  */
"home.signup_email" = "Email";

/* recover_email  */
"home.signup_email_recover" = "Recover Email";

/* password  */
"home.password" = "Enter your __Password__:";

I'm expecting to modify this file to obtain this:

/* Title  */
"home.title" = "Welcome";

/* Email  */
"home.signupEmail" = "Email";

/* recover_email  */
"home.signupEmailRecover" = "Recover Email";

/* password  */
"home.password" = "Enter your __Password__:";

I tried using gsed with something like this but unfortunately, I'm not able to stop at after the = character.

find . -name "*.strings" | xargs gsed -i -e '/=/! s/_\([a-z]\)/\U\1/gi'

Any idea on how to stop replacing _ after =?

Thanks!


Solution

You can use

sed ':a;s/^\([^=]*\)_\([[:alpha:]]\)/\1\U\2\E/;ta'

You may also use [[:lower:]] instead of [[:alpha:]] if you want to only replace _ + lowercase letters.

Details:

  • :a - set an a label
  • s/^\([^=]*\)_\([[:alpha:]]\)/\1\U\2\E/ - find and capture into Group 1 any zero or more chars other than a = char, then match a _ and then capture any letter into Group, and replace with Group 1 + an uppercased letter in Group 1
  • ta - if there was a successful replacement, jump back to a label position.

See the 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&section_id=foo)";'
sed ':a;s/^\([^=]*\)_\([[:alpha:]]\)/\1\U\2\E/;ta' <<< "$s"

Output:

/* 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&section_id=foo)";


Answered By - Wiktor Stribiżew
Answer Checked By - Mildred Charles (WPSolving Admin)