I want to convert my_long_variable
to myLongVariable
in sed.
This works:
echo "my_long_variable" | sed -r 's/(^|_)([a-z])/\U\2/g' | sed -r 's/^(.)/\l\1/g'
Is there a more elegant way to do that with sed?
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])/\U\1/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]\)/\U\1/g
This is portable (POSIX compliant) and will work on any system that has vi
, even the most minimal implementation.
ex
(the predecessor of vi
), 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\$
:s/_\([a-z]\)/\U\1/g
fails to convert the first character of the variable name to upper case. (Edit: I guess that's what OP desired.)
\$\endgroup\$
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])/\U\1/gi' | sed -r 's/^([A-Z])/\l\1/'
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])/\U\1/gi;s/^([A-Z])/\l\1/'
outputs
somethingWithABitOfVariety
or even
echo "Something & some_special! chars" | sed -E 's/[^a-z]+([a-z])/\U\1/gi;s/^([A-Z])/\l\1/'
outputs
somethingSomeSpecialChars
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\$
Commented
Mar 11, 2020 at 19:49
\U
!
\$\endgroup\$
sed
processes was already mentioned in Wildcard's answer.
\$\endgroup\$
Commented
Mar 17, 2020 at 9:37