Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linux bash, camel case string to separate by dash

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?

like image 830
armandfp Avatar asked Dec 14 '11 10:12

armandfp


People also ask

What is tolower in Unix?

tolower(str) : Return a copy of the string str, with all the uppercase characters in str translated to their corresponding lowercase counterparts. Non-alphabetic characters are left unchanged.

How to convert upper case to lower case in Shell?

The ^ operator converts to uppercase, while , converts to lowercase. If you double-up the operators, ie, ^^ or ,, , it applies to the whole string; otherwise, it applies only to the first letter (that isn't absolutely correct - see "Advanced Usage" below - but for most uses, it's an adequate description).

How to convert upper case to lower case in Linux?

You can change the case of the string very easily by using tr command. To define uppercase, you can use [:upper:] or [A-Z] and to define lowercase you can define [:lower:] or [a-z].

How to convert capital letters to small letters in Linux?

Using SED to convert case [a-z] is the regular expression which will match lowercase letters. \U& is used to replace these lowercase letters with the uppercase version. [A-Z] is the regular expression which will match uppercase letters. \L& is used to replace these uppercase letters with the lowercase version.


4 Answers

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"
like image 145
dogbane Avatar answered Oct 20 '22 18:10

dogbane


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

like image 20
4ndrew Avatar answered Oct 20 '22 18:10

4ndrew


echo MyDirectoryFileLine | perl -ne 'print lc(join("-", split(/(?=[A-Z])/)))'

prints my-directory-file-line

like image 8
eumiro Avatar answered Oct 20 '22 17:10

eumiro


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
like image 4
Peter Avatar answered Oct 20 '22 17:10

Peter