использование sed для преобразования Camel-регистра в under_score

У меня есть 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 никогда не должен содержать специальные символы или пробелы

0
задан 15 January 2020 в 10:18

2 ответа

Необходимо полагать, что изменение случая является меткой слова. Пространство _ должны быть помещены незадолго до изменения случая

Попробуйте это:

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:]'
0
ответ дан 15 January 2020 в 22:18

Проблема то, что Ваш \([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
0
ответ дан 15 January 2020 в 22:18

Другие вопросы по тегам:

Похожие вопросы: