Home > Software design >  Converting PascalCase string to kebab-case in bash without sed
Converting PascalCase string to kebab-case in bash without sed

Time:09-22

I have this working bash one-liner which converts PascalCase to kebab-case using sed:

foo="TestPascalCaseString"
echo $foo | sed -r 's/([a-z0-9])([A-Z])/\1-\2/g' | tr '[:upper:]' '[:lower:]'
output: test-pascal-case-string

However, this is used in a script which needs to be portable between common Linux distros, WSL on Windows, and both new and older versions of macOS.

On older versions of macOS, the script fails with:

sed: illegal option -- r

I've solved this problem for users of any macOS version by having them brew install gsed first, and have the script use gsed instead of sed. This works, but then Linux users don't have a gsed binary so they'd need to change the script back to using sed.

So I am trying to re-create this with a pure bash solution, or any other tools that work consistently across all platforms, to eliminate the need for prerequisite tool installations or script modifications.

I've tried bash parameter substitution:

foo="TestPascalCaseString"
echo ${foo//[A-Z]/-}
output: -est-ascal-ase-tring

and that replaces the uppercase letters with hyphens, but I don't know how to keep the uppercase characters which it's replacing.

CodePudding user response:

With a loop, a regex and bash version >= 3.0:

foo="TestPascalCaseString"
while [[ "$foo" =~ (.*[a-z0-9])([A-Z].*) ]] && foo="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}"; do
  :  # do nothing
done
echo "${foo,,}"

Output:

test-pascal-case-string

CodePudding user response:

Using perl (Which I'm 99% sure still comes with OS X):

$perl -ne 'print lc s/[[:lower:]\d]\K[[:upper:]]/-$&/rg' <<<"TestPascalCaseString"
test-pascal-case-string
  • Related