linux bash,camel case字符串由dash分隔

时间:2011-12-14 10:31:58

标签: linux bash camelcasing

有没有办法转换这样的东西:

MyDirectoryFileLine

my-directory-file-line

我找到了一些方法将所有字母转换为大写或小写,但不是这样;任何想法?

9 个答案:

答案 0 :(得分:22)

您可以使用s/\([A-Z]\)/-\L\1/g查找大写字母并用短划线替换它,它是小写字母。但是,这会在行的开头给你一个破折号,所以你需要另一个sed表达式来处理它。

这应该有效:

sed --expression 's/\([A-Z]\)/-\L\1/g' \
    --expression 's/^-//'              \
    <<< "MyDirectoryFileLine"

答案 1 :(得分:8)

我建议使用sed来做到这一点:

NEW=$(echo MyDirectoryFileLine        \
     | sed 's/\(.\)\([A-Z]\)/\1-\2/g' \
     | tr '[:upper:]' '[:lower:]')

UPD 我忘了转换为小写,更新代码

答案 2 :(得分:8)

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

打印my-directory-file-line

答案 3 :(得分:1)

此处发布的解决方案均不适合我。大多数人都不能很好地支持多个平台。来自@ 4ndrew的那个很接近,但是在边缘情况下,它们彼此相邻有多个大写字符(例如:FooMVPClient变成foo-mv-pclient而不是foo-mvp-client)。

这对我有用:

echo "MyDirectoryMVPFileLine"              \
| sed 's/\([a-z]\)\([A-Z]\)/\1-\2/g'       \
| sed 's/\([A-Z]\{2,\}\)\([A-Z]\)/\1-\2/g' \
| tr '[:upper:]' '[:lower:]'

输出:

my-directory-mvp-file-line

答案 4 :(得分:0)

使用 GNU sed:

echo "MyDirectoryFileLine"|sed -e 's/\([A-Z]\)/-\L\1/g'

如果这让你感到困扰,你只需要去除第一个破折号:

echo "MyDirectoryFileLine"|sed -e 's/\([A-Z]\)/-\L\1/g' -e 's/^-//'

使用 BSD ,它会更长一点:

echo "MyDirectoryFileLine"|sed -e 's/\([A-Z]\)/-\1/g' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' -e 's/^-//'

更新:BSD版本将与GNU版本一起使用,因此我建议使用后者。

答案 5 :(得分:0)

这可能对您有用:

<<<"MyDirectoryFileLine" sed 's/[A-Z]/-\l&/g;s/.//'
my-directory-file-line

答案 6 :(得分:0)

@bilalq的答案略有变化,涵盖了更多可能的极端情况:

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:]'

输出仍然是:

my-directory-mvp-file-line

而且:

WhatADeal -> what-a-deal
TheMVP -> the-mvp
DoSomeABTesting -> do-some-ab-testing
The3rdThing -> the-3rd-thing
The3Things -> the-3-things
ThingNumber3 -> thing-number-3

答案 7 :(得分:0)

echo "SomeACRONYMInCamelCaseString" \
 | sed -e 's/\([a-z]\)\([A-Z]\)/\1-\L\2/' \
 | sed -e 's/\(.*\)/\L\1/')

sed -e 's/\([a-z]\)\([A-Z]\)/\1-\L\2/'仅在大写字母后接连字符和小写字母的情况下才使用连字符和小写字母。 sed -e 's/\(.*\)/\L\1/'将整个字符串小写

答案 8 :(得分:0)

我的适度贡献与“/”一起使用(可能用于目录名称或 github 存储库名称)。它不像它可能的那样干净,但可以完成工作。我使用@Peter 的贡献作为基础,然后稍微调整了一下。

function kebab_case() {
  echo -n "$1" |\
  sed 's/\([^A-Z+]\)\([A-Z0-9]\)/\1-\2/g' |\
  sed 's/\([0-9]\)\([A-Z]\)/\1-\2/g' |\
  sed 's/\([A-Z]\)\([0-9]\)/\1-\2/g' |\
  sed 's/--/-/g' |\
  sed 's/\([\/]\)-/\1/g' |\
  tr '[:upper:]' '[:lower:]'
}

function assert_kebab_equal() {
    local Actual
    local Expected
    Expected="$1"
    Actual="$(kebab_case "$2")"

    if [ "${Expected}" != "${Actual}" ]; then
      echo Error:
      echo "  Actual: ${Actual}"
      echo "Expected: ${Expected}"
    else
      echo "$2" "$1" | awk '{ printf "%-30s -> %-40s\n", $1, $2}'
    fi
}

assert_kebab_equal "abc-def" "AbcDef"
assert_kebab_equal "/abc-def-ghi/def" "/AbcDef-Ghi/Def"
assert_kebab_equal "/ab-cd-ef" "/AbCdEf"
assert_kebab_equal "repo-owner/repo-name" "RepoOwner/RepoName"
assert_kebab_equal "repo-12-owner/repo-12-name" "Repo12Owner/Repo12Name"
assert_kebab_equal "repo-12-3-owner/repo-12-name" "Repo12-3Owner/Repo12Name"
assert_kebab_equal "repo-owner/repo-name" "REPO-OWNER/REPO-NAME"
assert_kebab_equal "repo-owner-2/repo-name" "REPO-OWNER2/REPO-NAME"
assert_kebab_equal "repo-1-owner" "REPO1-OWNER"
assert_kebab_equal "repo-1-owner-1/22-repo-2-name" "REPO1-OWNER1/22REPO-2NAME"


# Outputs:

AbcDef                         -> abc-def                                 
/AbcDef-Ghi/Def                -> /abc-def-ghi/def                        
/AbCdEf                        -> /ab-cd-ef                               
RepoOwner/RepoName             -> repo-owner/repo-name                    
Repo12Owner/Repo12Name         -> repo-12-owner/repo-12-name              
Repo12-3Owner/Repo12Name       -> repo-12-3-owner/repo-12-name            
REPO-OWNER/REPO-NAME           -> repo-owner/repo-name                    
REPO-OWNER2/REPO-NAME          -> repo-owner-2/repo-name                  
REPO1-OWNER                    -> repo-1-owner                            
REPO1-OWNER1/22REPO-2NAME      -> repo-1-owner-1/22-repo-2-name