dingo_d
dingo_d

Reputation: 11680

sed Capital_Case not working

I'm trying to convert a string that has either - (hyphen) or _ (underscore) to Capital_Case string.

#!/usr/bin/env sh

function cap_case() {
  [ $# -eq 1 ] || return 1;
  _str=$1;
  _capitalize=${_str//[-_]/_} | sed -E 's/(^|_)([a-zA-Z])/\u\2/g'
  echo "Capitalize:"
  echo $_capitalize
  return 0
}

read string
echo $(cap_case $string)

But I don't get anything out.

First I am replacing any occurrence of - and _ with _ ${_str//[-_]/_}, and then I pipe that string to sed which finds the first letter, or _ as the first group, and then the letter after the first group in the second group, and I want to uppercase the found letter with \u\2. I tried with \U\2 but that didn't work as well.

I want the string some_string to become

Some_String

And string some-string to become

Some_String

I'm on a mac, using zsh if that is helpful.

Upvotes: 2

Views: 574

Answers (5)

Toby Speight
Toby Speight

Reputation: 30871

You didn't assign to _capitalize - you set a _capitalize environment variable for the empty command that you piped into sed.

You probably meant

_capitalize=$(<<<"${_str//[-_]/_}" sed -E 's/(^|_)([a-zA-Z])/\1\u\2/g')

Note also that ${//} isn't standard shell, so you really ought to specify an interpreter other than sh.

A simpler approach would be simply:

#!/bin/sh

cap_case() {
    printf "Capitalize: "
    echo "$*" | sed -e 'y/-/_/' -e 's/\(^\|_\)[[:alpha:]]/\U&/g'
}

echo $(cap_case "snake_case")

Note that the \u / \U replacement is a GNU extension to sed - if you're using a non-GNU implementation, check whether it supports this feature.

Upvotes: 0

ctac_
ctac_

Reputation: 2491

You can try this gnu sed

echo 'some_other-string' | sed -E 's/(^.)/\u&/;s/[_-](.)/_\u\1/g'

Explains :

s/(^.)/\u&/

(^.) match the first char and \u& put the match in capital letter.

s/[_-](.)/_\u\1/g

[_-](.) capture a char preceded by _ or - and replace it by _ and the matched char in capital letter.

The g at the end tell sed to make the replacement for each char which meet the criteria

Upvotes: 0

kyodev
kyodev

Reputation: 583

pure bash:

#!/bin/bash

camel_case(){
    local d display string
    declare -a strings          # = scope local

    [ "$2" ] && d="$2" || d=" " # optional output delimiter
    ifs_ini="$IFS"
    IFS+='_-'                   # we keep initial IFS
    strings=( "$1" )            # array
    for string in ${strings[@]} ; do
        display+="${string^}$d"
    done
    echo "${display%$d}"
    IFS="$ifs_ini"
}

camel_case "some-string_here" "_" 
camel_case "some-string_here some strings here" "+" 
camel_case "some-string_here some strings here"

echo "$BASH_VERSION"

exit

output:

Some_String_Here
Some+String+Here+Some+Strings+Here
Some String Here Some Strings Here
4.4.18(1) release

Upvotes: 2

chepner
chepner

Reputation: 531808

This being zsh, you don't need sed (or even a function, really):

$ s=some-string-bar
$ print ${(C)s:gs/-/_}
Some_String_Bar

The (C) flag capitalizes words (where "words" are defined as sequences of alphanumeric characters separated by other characters); :gs/-/_ replaces hyphens with underscores.

If you really want a function, it's cap_case () { print ${(C)1:gs/-/_} }.

Upvotes: 2

RavinderSingh13
RavinderSingh13

Reputation: 133610

EDIT: More generic solution here to make each field's first letter Capital.

echo "some_string_other" | awk -F"_" '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1)) substr($i,2)}} 1' OFS="_"

Following awk may help you.

echo "some_string" | awk -F"_" '{$1=toupper(substr($1,1,1)) substr($1,2);$2=toupper(substr($2,1,1)) substr($2,2)} 1' OFS="_"

Output will be as follows.

echo "some_string" | awk -F"_" '{$1=toupper(substr($1,1,1)) substr($1,2);$2=toupper(substr($2,1,1)) substr($2,2)} 1' OFS="_"
Some_String

Upvotes: 2

Related Questions