LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   zsh - zmv - do not change case if there are more than one consecutive uppercase letters (https://www.linuxquestions.org/questions/linux-newbie-8/zsh-zmv-do-not-change-case-if-there-are-more-than-one-consecutive-uppercase-letters-4175678542/)

blueray 07-11-2020 09:52 AM

zsh - zmv - do not change case if there are more than one consecutive uppercase letters
 
I am using the following command

Code:

zmv -n -Q '(**/)(*[[:upper:]]*)(/)' '${1}${(L)${2//(#b)([[:upper:]])/-$match[1]}#-}'
to transform

Code:

    % tree
    .
    ├── EmptyFile.txt
    ├── FirstDirectoryName
    │  ├── FourthDirectoryName
    │  ├── secondDirectoryName
    │  └── thirdDirectoryName
    ├── FourthDirectoryName
    ├── secondDirectoryName
    └── thirdDirectoryName

To

Code:

    % tree
    .
    ├── EmptyFile.txt
    ├── first-directory-name
    │  ├── fourth-directory-name
    │  ├── second-directory-name
    │  └── third-directory-name
    ├── fourth-directory-name
    ├── second-directory-name
    └── third-directory-name

However there is a small problem.

I do not want to lowercase if there are more than one consecutive uppercase letters. I just want to put `-` behind the capital letters given it is not in the beginning.

Code:

    % tree
    .
    ├── DDDDDDD
    ├── FirstFolderToRename
    │  ├── DDDDDDD
    │  └── ThisIsDDDDD
    ├── secondFolderToRename
    │  ├── DDDDDDD
    │  └── ThisIsDDDDD
    └── ThisIsDDDDD

Current Output

Code:

    % zmv -n -Q '(**/)(*[[:upper:]]*)(/)' '${1}${(L)${2//(#b)([[:upper:]])/-$match[1]}#-}'
    mv -- FirstFolderToRename/DDDDDDD FirstFolderToRename/d-d-d-d-d-d-d
    mv -- FirstFolderToRename/ThisIsDDDDD FirstFolderToRename/this-is-d-d-d-d-d
    mv -- secondFolderToRename/DDDDDDD secondFolderToRename/d-d-d-d-d-d-d
    mv -- secondFolderToRename/ThisIsDDDDD secondFolderToRename/this-is-d-d-d-d-d
    mv -- DDDDDDD d-d-d-d-d-d-d
    mv -- FirstFolderToRename first-folder-to-rename
    mv -- secondFolderToRename second-folder-to-rename
    mv -- ThisIsDDDDD this-is-d-d-d-d-d

Expected Output

Code:

    mv -- FirstFolderToRename/DDDDDDD FirstFolderToRename/DDDDDDD
    mv -- FirstFolderToRename/ThisIsDDDDD FirstFolderToRename/this-is-DDDDD
    mv -- secondFolderToRename/DDDDDDD secondFolderToRename/DDDDDDD
    mv -- secondFolderToRename/ThisIsDDDDD secondFolderToRename/this-is-DDDDD
    mv -- DDDDDDD DDDDDDD
    mv -- FirstFolderToRename first-folder-to-rename
    mv -- secondFolderToRename second-folder-to-rename
    mv -- ThisIsDDDDD this-is-DDDDD


shruggy 07-11-2020 10:41 AM

Try to replace [[:upper:]] with [[:upper:]][[:lower:]] and (#b) with (#m):
Code:

'${1}${${2//(#m)[[:upper:]][[:lower:]]/-${(L)MATCH}}#-}'
This won't put the dash before DDDDD though.

Consider doing this in two steps then. First, put dashes between words:
Code:

zmv -n -Q '(**/)(*[A-Z]*)(/)' '$1${2//(#b)([a-z])([A-Z])/$match[1]-$match[2]}'
Then, change the case:
Code:

zmv -n Q '(**/)(*[A-Z][a-z]*)(/)' '$1${2//(#m)[A-Z][a-z]/${(L)MATCH}}'

blueray 07-11-2020 10:36 PM

Thank you very much. I have made a function like

Code:

function CamelToKebab() {

    zmv -Q '(**/)(*[A-Z]*)(/)' '$1${2//(#b)([a-z])([A-Z])/$match[1]-$match[2]}'
    zmv -Q '(**/)(*[A-Z][a-z]*)(/)' '$1${2//(#m)[A-Z][a-z]/${(L)MATCH}}'

}

Can you please show me how to go back to pascal case? I mean I am looking for

Code:

function KebabToPascel() {
 ....
}


blueray 07-12-2020 01:08 AM

I think the process should be simple

1. Capitalize First Character
2. Capitalize Every Character After `-`
3. Remove all `-`

So far I have figured out 1 & 3.

Code:

function KebabToPascal () {
    zmv -n -Q '(**/)(*-*)(/)' '$1${(U)2:0:1}${2#?}'
    // Capitalize Every Character After `-`
    zmv -n -Q '(**/)(*-[a-z]*)(/)' '$1${2//(-##)/}'
}

So the question boils down to How To Capitalize Every Character After `-`

blueray 07-12-2020 02:15 AM

Alhamdulillah. The function that is working is

Code:

function kebabToPascal () {
    zmv -Q '(**/)(*-*)(/)' '$1${(U)2:0:1}${2#?}'
    zmv -Q '(**/)(*-[a-z]*)(/)' '$1${2//(#m)-[a-z]/${(U)MATCH}}'
    zmv -Q '(**/)(*-*)(/)' '$1${2//-##/}'
}



All times are GMT -5. The time now is 07:14 PM.