#shell #sed
#оболочка #sed
Вопрос:
Я хочу преобразовать текст в переменной bash, т. Е. HttpStatus.NOT_FOUND
в status().isNotFound()
, и я выполнил это с помощью sed
:
result=HttpStatus.NOT_FOUND
result=$(echo $result | cut -d'.' -f2- | sed -r 's/(^|_)([A-Z])/L2/g' | sed -E 's/([[:lower:]])|([[:upper:]])/U1L2/g')
echo "status().is$result()"
Вывод:
status().isNotFound()
Как вы можете видеть здесь, я использую 2 sed
команды.
Есть ли способ достичь того же результата с помощью 1 sed
или любым другим более простым способом?
Ответ №1:
Поскольку это включает в себя вставку большого количества нового текста в заменяющую часть, sed
команда может быть подробно написана, как показано ниже. Просто передайте содержимое переменной по каналу, не используя cut
result=HttpStatus.NOT_FOUND
echo "$result" |
sed -E 's/^.*(Status).([[:upper:]])([[:upper:]] )_([[:upper:]])([[:upper:]] )$/L1().isu2L3u4L5()/g'
Идея заключается в том, чтобы добавить функции преобразования регистра GNU sed
в захваченные группы. Таким образом, мы фиксируем
(Status)
в1
котором мы просто вводим всю строку в нижний регистр, а затем добавляем().is
к результату- Следующей захваченной группой
2
будет первый символ верхнего регистра, следующий за.
которым будетN
, а остальная часть строкиOT
в3
. Мы сохраняем вторую как таковую и делаем нижний регистр третьей группы. - Та же последовательность, что и выше, повторяется для следующего слова
FOUND
в4
и5
. L
,u
являются операторами преобразования регистра, доступными в GNUsed
.
Если вы хотите изменить только часть за пределами .
в camelCase, то вы можете использовать sed
как
result=HttpStatus.NOT_FOUND
result=$(echo "$result" |
sed -E 's/^.*.([[:upper:]])([[:upper:]] )_([[:upper:]])([[:upper:]] )/u1L2u3L4/g')
echo "status().is$result()"
Комментарии:
1. @KNDheeraj: Вам просто нужно выполнить
echo "$result" |
передsed
командой2. Я выполнил эту команду
echo "status().is$result()" | sed -E 's/^.*(Status).([[:upper:]])([[:upper:]] )_([[:upper:]])([[:upper:]] )$/l1().is2L3u4L5()/g'
и выдал мнеstatus().isHttpStatus.OK()
3. @KNDheeraj: Каков ваш ввод? в вопросе, который вы предоставили
HttpStatus.NOT_FOUND
и теперь тестируете с помощью"status().is$init()"
why? каково значениеinit
?4. Завершите фрагмент,
result=HttpStatus.NOT_FOUND echo $result | cut -d'.' -f2- | sed -E 's/^.*(Status).([[:upper:]])([[:upper:]] )_([[:upper:]])([[:upper:]] )$/l1().is2L3u4L5()/g'
который я пробовал, который генерирует этот вывод:NOT_FOUND
который не то, что мне требовалось!!5.Это чертовски превосходит мои 3
tr
вызова и одинsed
:)
@Inian — все, к чему он пытается добраться, находится в"NotFound"
inresult
, так что общая строка"status().is$result()"
равна"status().isNotFound()"
. (что немного сократит время выполнения)
Ответ №2:
Это может сработать для вас (GNU sed):
<<<"$result" sed -r 's/.*(Status).(.*)_(.*)/L1().isu2u3()/'
Используйте сопоставление с шаблоном / группировку / обратные ссылки. Большинство RHS — символов в нижнем регистре, поэтому используйте L
метасимвол для преобразования из Status...
в нижний регистр, а в верхний регистр — только начало слов, используя u
который преобразует в верхний регистр только следующий символ.
Примечание: L
и аналогично U
преобразует все последующие символы в нижний / верхний регистр до E
или U
/ L
, l
и u
прерывает это только для следующего символа.
Ответ №3:
Поскольку вы используете GNU sed ( -r
переключатель), вот другое sed
решение,
только немного более краткое и безопасное по локали:
$ result=HttpStatus.NOT_FOUND
$ echo "$result" | sed -r 's/^.*([A-Z][a-z]*).([a-zA-Z])([a-zA-Z]*)_([a-zA-Z])([a-zA-Z]*)/L1().isu2L3U4L5()/'
status().isNotFound()
Еще более сжатый способ sed
— это:
echo "$result" | sed -r 's/^.*([A-Z][a-z]*).([a-zA-Z]*)_([a-zA-Z]*)/L1().isu2u3()/'
Они оба не чувствительны к регистру для второй части, например, .nOt_fOuNd
также работает здесь.
И решение GNU awk
:
echo "$result" | awk 'function cap(str){return (toupper(substr(str,1,1)) tolower(substr(str,2)))}match($0, /([A-Z][a-z]*).([a-zA-Z]*)_([a-zA-Z]*)/, m){print tolower(m[1]) ".is" cap(m[2]) cap(m[3]) "()"}'
Ответ №4:
Вы можете использовать параметр sed «-e» для объединения множественных выражений.