Как прописать первый символ подстроки в верхнем регистре, только если она имеет длину более 3 символов - PullRequest
0 голосов
/ 17 января 2019

Мне нужно преобразовать эту строку:

меня зовут пользователь отсюда не там.

до:

Мое имя это Пользователь отсюда не Там

Подробности в том, что мне нужно вывести первый символ любого слова с более чем 3 символами. Просто это. Я безуспешно пытаюсь с этими командами:

echo $FOO | tr '[:upper:]' '[:lower:]' | sed -e "s/\b\(.\)/\u\1/g"

Все остальное должно быть в нижнем регистре.

Ответы [ 4 ]

0 голосов
/ 17 января 2019

Это может сработать для вас (GNU sed):

sed -E 's/^\w+|\b\w{4,}\b/\u&/g' file

Верхний регистр - первый символ слова, если это слово появляется в строке, начинающейся со слова или любого слова длиной 4 или более символов

0 голосов
/ 17 января 2019

Использование GNU sed, (и bash):

F="my name is user from here not there."
sed -E 's/^./\u&/;s/([[:space:]])([[:alpha:]]{4})/\1\u\2/g' \ 
    <<< "${F,,}"

или

sed -E 's/^./\u&/;s/(\s)(\w{4})/\1\u\2/g' <<< "${F,,}"

Выход:

My Name is User From Here not There.

Примечания:

"${F,,}" - это расширение параметра модификации регистра bash , возвращает строчную версию $F, которая становится входом для sed.

GNU sed предлагает некоторые полезные синонимы и сокращения для обычных regex классов символов. Класс символов [a-zA-Z0-9_] может быть сокращен до [[:alpha:]_] или еще проще \w.

Хотя \u выглядит как регулярное выражение , это не так. Это «особая последовательность» , используемая только в s ubstitute текст замены команды - \u означает «перевод следующего символа в верхний регистр» .

& относится к любому первому регулярному выражению в команде s ubstitute . Сравните следующее:

sed 's/./&/'          <<< foo  # outputs "f"
sed 's/./&/g'         <<< foo  # outputs "foo"
sed 's/./&&&&/g'      <<< foo  # outputs "ffffoooooooo"
sed 's/./\u&&&\u&/g'  <<< foo  # outputs "FffFOooOOooO"
sed 's/.*/&&&&/'      <<< foo  # outputs "foofoofoofoo"

Подробнее см. GNU sed info страницы .

0 голосов
/ 17 января 2019

tr не совсем подходящий инструмент для этой работы; он вообще не знает о контексте.

Некоторые варианты sed имеют расширения Perl или vi для регулярных выражений, но это не может быть реально решено с помощью sed, либо.

Perl на помощь:

bash$ foo="my name is user from here not there."

bash$ echo "$foo" | perl -pe 's/\w{4,}/\u$&/g'
my Name is User From Here not There.

Это делает то, что вы на самом деле просите, но не то, что вы хотите. Возможно, добавьте условие, чтобы прописать первое слово ввода отдельно или переключиться на библиотеку, например Lingua :: EN :: Titlecase .

Обратите также внимание на то, как мы не используем верхний регистр для наших личных переменных (поскольку переменные в верхнем регистре зарезервированы для системного использования) и всегда заключают в кавычки наши строки оболочки.

0 голосов
/ 17 января 2019

Не могли бы вы попробовать следующее.

echo "my name is user from here not there." |
awk '{for(i=1;i<=NF;i++)
    if(length($i)>3){$i=toupper(substr($i,1,1)) substr($i,2)}}
    1'

Результат:

my Name is User From Here not There.
...