I want to convert my_long_variable
to myLongVariable
in sed.
This works:
echo "my_long_variable" | sed -r 's/(^|_)([a-z])/\U2円/g' | sed -r 's/^(.)/\l1円/g'
Is there a more elegant way to do that with sed?
3 Answers 3
First of all, prefer -E
to -r
; it's more portable.
However, since you're using the \U
GNU extension in any case, this isn't that crucial.
Second, I assume echo
is a stand-in for a more complex command. If there is in fact no complex command, consider using a Here String or a Here Doc instead.
Crucially, you don't need to fire up two Sed processes just to run two Sed commands. Sed is a complete programming language in itself. Just separate the two commands with a semicolon: sed 's/foo/bar/;s/frip/baz/'
However, in this case you don't even need that, because you only need a single substitution.
sed -E 's/_([a-z])/\U1円/g' <<< my_long_variable
There is another aspect here. You shouldn't often need to change case in scripts (and certainly not in Bash). But if you're doing this in your editor, you should use vi
rather than a Bash script for the editing. \U
and its relatives are standard features of vi
, though not of Sed.
So within vi
, on a line of text containing only the variable name, you can use:
:s/_\([a-z]\)/\U1円/g
This is portable (POSIX compliant) and will work on any system that has vi
, even the most minimal implementation.
-
1\$\begingroup\$ Thanks! This is part of a code generation tool (with different modules using different languages with different conventions), so vi won't do, it needs to be automated. \$\endgroup\$Nicolas Raoul– Nicolas Raoul2016年11月18日 04:49:41 +00:00Commented Nov 18, 2016 at 4:49
-
\$\begingroup\$ @NicolasRaoul, gotcha! For scripted text edits, you may want to learn
ex
(the predecessor ofvi
), which is designed for editing text files (whereas Sed is the stream editor)—and is fully portable. I've written extensively on its use on the Unix & Linux Stack Exchange. \$\endgroup\$Wildcard– Wildcard2016年11月18日 05:13:33 +00:00Commented Nov 18, 2016 at 5:13 -
\$\begingroup\$ The vi command
:s/_\([a-z]\)/\U1円/g
fails to convert the first character of the variable name to upper case. (Edit: I guess that's what OP desired.) \$\endgroup\$nibot– nibot2023年11月03日 17:20:55 +00:00Commented Nov 3, 2023 at 17:20
Why try to match for (^|_)
? You are anyway modifying it at the end, so just skip the first character entirely:
echo "my_long_variable" | sed -r 's/_([a-z])/\U1円/gi' | sed -r 's/^([A-Z])/\l1円/'
The above pattern will take care of cases where you start with:
Some_var_Iable
In addition to the other good suggestions, don't pipe sed to another invocation of sed, use a semi-colon to separate multiple commands.
Also you might want to make your toCamelCase
method more generic, e.g.
echo "Something_with-a bit_of Variety" | sed -E 's/[ _-]([a-z])/\U1円/gi;s/^([A-Z])/\l1円/'
outputs
somethingWithABitOfVariety
or even
echo "Something & some_special! chars" | sed -E 's/[^a-z]+([a-z])/\U1円/gi;s/^([A-Z])/\l1円/'
outputs
somethingSomeSpecialChars
-
1\$\begingroup\$ Semicolons are not portable to anything other than GNU
sed
. You can use-e
to append more editing commands at the end, which is the portable way to do it. Other than that, welcome and good first post! \$\endgroup\$S.S. Anne– S.S. Anne2020年03月11日 19:49:52 +00:00Commented Mar 11, 2020 at 19:49 -
\$\begingroup\$ Fair point, but then neither is
\U
! \$\endgroup\$spikyjt– spikyjt2020年03月11日 20:06:21 +00:00Commented Mar 11, 2020 at 20:06 -
\$\begingroup\$ Not using multiple
sed
processes was already mentioned in Wildcard's answer. \$\endgroup\$Toby Speight– Toby Speight2020年03月17日 09:37:57 +00:00Commented Mar 17, 2020 at 9:37 -
\$\begingroup\$ @TobySpeight you are correct - somehow I missed that! Should I downvote myself for skim reading?! Perhaps I should edit my answer just to demonstrate the general conversion to camel case from any string with special chars etc. \$\endgroup\$spikyjt– spikyjt2020年03月19日 10:55:08 +00:00Commented Mar 19, 2020 at 10:55