linux bash, camel case string to separate by dash

删除回忆录丶 提交于 2019-11-27 20:37:01
dogbane

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"
4ndrew

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

bilalq

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!