Преобразование текста из HttpStatus.NOT_FOUND в status().isNotFound() в bash

#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 являются операторами преобразования регистра, доступными в GNU sed .

Если вы хотите изменить только часть за пределами . в 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" in result , так что общая строка "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» для объединения множественных выражений.