Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a strings:

AddData
TestSomething
TellMeWhoYouAre

and so on. I want to add space before uppercase letters. How can I do it?

share|improve this question
7  
What do you want to do when there are consecutive upper case letters? example IClimbALadder – glenn jackman 16 hours ago
    
Actually I have a strings like ReadFileFromCDDrive and @Kusalananda 's solution works great. – HeroFromEarth 1 hour ago
up vote 9 down vote accepted

Using sed, and assuming you don't want a space in front of the word:

$ sed 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
Add Data
Test Something
Tell Me Who You Are

The substitution will look for an upper-case letter immediately following a another non-whitespace character, and insert a space in-between the two.

For strings with more than one consecutive upper-case character, like WeAreATeam, this produces We Are ATeam. To sort this, run the substitution a second time:

$ sed -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' \
      -e 's/\([^[:blank:]]\)\([[:upper:]]\)/\1 \2/g' file.in
share|improve this answer
1  
This answer won't add a space before an uppercase letter if it's preceded by an uppercase letter. Why write it that way, when the OP didn't put any such restriction on it? – LarsH 9 hours ago
    
@LarsH Fixed it. – Kusalananda 9 hours ago
    
No you didn't. You can't have overlapping matches to a regex, even with a g flag. Try echo ThisIsATest | sed 's/\(.\)\([[:upper:]]\)/\1 \2/g' (your command) to see why it doesn't work. – Wildcard 8 hours ago
    
@Wildcard Wonky, but works. Do you have a better suggestion using BREs? – Kusalananda 7 hours ago
    
It doesn't actually say no space at the start, so s/[A-Z]/ \0/g is entirely satisfactory... `s/[A-Z]/ \0/g;s/^ //' if you really care. – Michael Homer 7 hours ago

Perl, using lookbehind and lookahead zero-width regular expressions:

$ perl -pe 's/(?<=\w)(?=[A-Z])/ /g'  file.in 

Tell Me Who You Are                    ## TellMeWhoYouAre
I Am A Regular Expression User         ## IAmARegulaExpressionUser

This version is also separating consecutive uppercase letters.

share|improve this answer
sed -r -e "s/([^A-Z])([A-Z])/\1 \2/g"

Add space between a letter that is not an upper-case letter and a letter that is an upper-case letter

share|improve this answer
    
Brevity is acceptable, but fuller explanations are better.. Additionally, what's the point of [^^] ("not a caret (^)")? – Kusalananda 11 hours ago
    
@Kusalananda You're right. The space won't be inserted between ^ and Add in "^AddData". I've edited my answer. – ka3ak 11 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.