I want to convert
myLongVariable in sed.
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?
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It only takes a minute to sign up.Sign up to join this community
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:
First of all, prefer
-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:
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.
vi, on a line of text containing only the variable name, you can use:
This is portable (POSIX compliant) and will work on any system that has
vi, even the most minimal implementation.
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/'
echo "Something & some_special! chars" | sed -E 's/[^a-z]+([a-z])/\U\1/gi;s/^([A-Z])/\l\1/'