У меня есть sed сценарий, который может преобразовать Camel-регистр в under_score, который работает отлично для этого примера:
myvar="camelCase"
converted="$(echo $myvar | sed 's/\([A-Z]\)/_\L\1/g;s/^_//')"
echo converted
// result: camel_case
Однако у меня есть следующий случай:
myvar="camelCASE"
converted="$(echo $myvar | sed 's/\([A-Z]\)/_\L\1/g;s/^_//')"
echo converted
// result: camel_c_a_s_e
Результат, в котором я нуждаюсь в данном случае: camel_case.
чтобы быть ясным, финал sed сценарий должен работать на "Camel-регистр", а также "Camel-регистр" и "CAMEL-РЕГИСТР".
myvar никогда не должен содержать специальные символы или пробелы
Необходимо полагать, что изменение случая является меткой слова. Пространство _
должны быть помещены незадолго до изменения случая
Попробуйте это:
echo 'CamelCASECamelCase' \
| 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:]'
Проблема то, что Ваш \([A-Z]\)
только получает единственную прописную букву за один раз. Для фиксации этого в POSIX BRE sed можно использовать \([A-Z]\{1,\}\)
напр.
$ echo camelCASE | sed 's/\([A-Z]\{1,\}\)/_\L\1/g;s/^_//'
camel_case
По крайней мере, в GNU sed, ou может избежать специального режима продвижения _
только соответствуя после неразрыва слова
$ echo CamelCASE | sed 's/\B\([A-Z]\{1,\}\)/_\L\1/g'
Camel_case
Это немного более читаемо в ДО
$ echo CamelCASECamelCase | sed -E 's/\B([A-Z]+)/_\L\1/g'
Camel_casecamel_case
или даже (использование &
вместо явной группировки)
$ echo CamelCASECamelCase | sed -E 's/\B[A-Z]+/_\L&/g'
Camel_casecamel_case