Is there a way to convert something like this:
MyDirectoryFileLine
to
my-directory-file-line
I found some ways to convert all letters to uppercase or lowercase, but not in that way; any ideas?
You can use s/\([A-Z]\)/-\L\1/g
to find an upper case letter and replace it with a dash and it's lower case. However, this gives you a dash at the beginning of the line, so you need another sed expression to handle that.
This should work:
sed --expression 's/\([A-Z]\)/-\L\1/g' \
--expression 's/^-//' \
<<< "MyDirectoryFileLine"
I propose to use sed to do that:
NEW=$(echo MyDirectoryFileLine \
| sed 's/\(.\)\([A-Z]\)/\1-\2/g' \
| tr '[:upper:]' '[:lower:]')
UPD I forget to convert to lower case, updated code
echo MyDirectoryFileLine | perl -ne 'print lc(join("-", split(/(?=[A-Z])/)))'
prints my-directory-file-line
None of the solutions posted here worked for me. Most didn't support multiple platforms well. The one from @4ndrew was close, but it failed on edge cases that had multiple capitalized characters next to each other (example: FooMVPClient
turns into foo-mv-pclient
instead of foo-mvp-client
).
This worked for me:
echo "MyDirectoryMVPFileLine" \
| sed 's/\([a-z]\)\([A-Z]\)/\1-\2/g' \
| sed 's/\([A-Z]\{2,\}\)\([A-Z]\)/\1-\2/g' \
| tr '[:upper:]' '[:lower:]'
output:
my-directory-mvp-file-line
This might work for you:
<<<"MyDirectoryFileLine" sed 's/[A-Z]/-\l&/g;s/.//'
my-directory-file-line
With GNU sed:
echo "MyDirectoryFileLine"|sed -e 's/\([A-Z]\)/-\L\1/g'
You just need to strip the first dash if that's bothers you:
echo "MyDirectoryFileLine"|sed -e 's/\([A-Z]\)/-\L\1/g' -e 's/^-//'
With BSD sed it it's a bit longer:
echo "MyDirectoryFileLine"|sed -e 's/\([A-Z]\)/-\1/g' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' -e 's/^-//'
Update: the BSD version will work with the GNU version, so I recommend using the latter.
Slight variation on @bilalq's answer that covers some more possible edge cases:
echo "MyDirectoryMVPFileLine" \
| sed 's/\([^A-Z]\)\([A-Z0-9]\)/\1-\2/g' \
| sed 's/\([A-Z0-9]\)\([A-Z0-9]\)\([^A-Z]\)/\1-\2\3/g' \
| tr '[:upper:]' '[:lower:]'
output is still:
my-directory-mvp-file-line
but also:
WhatADeal -> what-a-deal
TheMVP -> the-mvp
DoSomeABTesting -> do-some-ab-testing
The3rdThing -> the-3rd-thing
The3Things -> the-3-things
ThingNumber3 -> thing-number-3
来源:https://stackoverflow.com/questions/8502977/linux-bash-camel-case-string-to-separate-by-dash