Intereting Posts
URL Rewrite на debian не работает удалять старые файлы журналов, кроме последнего (с буквенно-цифровой сортировкой) Установите близость процесса из сценария оболочки, когда он запускается Клиент электронной почты в Linux, который позволяет искать зашифрованную почту Как установить Windows 8 после арки? Является ли библиотека vdso shared (linux-vdso.so) библиотекой, которая содержит объектный код ядра (системные вызовы)? Существуют ли настольные почтовые клиенты, которые реализуют просмотр разговора в стиле gmail? Как глобально контролировать состояние системы? Отображение файла в другом файле Ручная установка pdftk не может найти библиотеку libgcj Напишите в FIFO только в том случае, если он существует Пространство имеет значение в crontab IPTABLES, чтобы разрешить ssh, ftp, pop и т. Д. С одного статического IP-адреса с открытым HTTP / SSL Изменить сопоставления ключей для xfce4-terminal Возможно ли PXE в сети 802.1x для LTSP?

awk или sed в нижнем регистре / в верхнем регистре только один символ в строке?

Есть способ, как прописные или строчные буквы только одного символа в некоторой строке?

Пример ввода:

syslog_apr_24_30 syslog_mar_01_17 

Желаемый результат:

 syslog_Apr_24_30 syslog_Mar_01_17 

Обратите внимание, пожалуйста, в верхнем регистре начала месяца.

Я пробовал awk но я недостаточно хорош, чтобы заставить его работать.

Вы можете использовать \u в GNU sed для прописных букв:

 sed -e 's/_\(.\)/_\u\1/' input 

Perl делает то же самое:

 perl -pe 's/_(.)/_\u$1/' input 

\l делает обратное.

AWK:

 echo "syslog_apr_24_30" | awk -F'_' '{print $1"_"toupper(substr($2,1,1)) substr($2,2) "_"$3"_"$4}' 

Версия Awk с подстроками и toupper

 awk 'BEGIN{ FS=OFS="_"} { cap=toupper(substr($2,1,1)); lower=substr($2,2,3); $2 = cap lower; print }' list.txt 

Пример прогона:

 $ awk 'BEGIN{ FS=OFS="_"} { cap=toupper(substr($2,1,1)); lower=substr($2,2,3);$2 = cap lower; print }' list.txt syslog_Apr_24_30 syslog_Mar_01_17 

Использование awk :

 awk -F_ '{ printf "%s_%s_%s_%s",$1,toupper(substr($2,1,1))substr($2,2,2),$3,$4"\n" }' foo 

или

 awk -F_ '{ for(i=1;i<=NF;i++) { if(i==2){ printf "%s",toupper(substr($i,1,1))substr($i,2,length($i)-1) } else {printf "%s",$i} if(i<NF) {printf "%s","_"} } printf "%s","\n"}' foo 

пример

 % cat foo syslog_apr_24_30 syslog_mar_01_17 % awk -F_ '{for(i=1;i<=NF;i++) {if(i==2){printf "%s",toupper(substr($i,1,1))substr($i,2,length($i)-1)} else {printf "%s",$i} if(i<NF) {printf "%s","_"}} printf "%s","\n"}' foo syslog_Apr_24_30 syslog_Mar_01_17 % awk -F_ '{printf "%s_%s_%s_%s",$1,toupper(substr($2,1,1))substr($2,2,2),$3,$4"\n"}' foo syslog_Apr_24_30 syslog_Mar_01_17 

Вот подход Perl:

 $ perl -pe 's/_./uc($&)/e' file syslog_Apr_24_30 syslog_Mar_01_17 

-p вызывает печать каждой строки после применения сценария, заданного -e . Подстановка заменяет первый экземпляр _ и символ, следующий за ним самим ( $& – все, что было сопоставлено) верхним обсаженным ( uc() ), The e в конце оператора замещения ( s///e ) необходимо в для оценки выражений.

Другой perl :

 perl -F_ -anle '$F[1] = ucfirst $F[1];print join "_", @F' 

Pure Bash 4.x, используя регулярное выражение, чтобы выбрать ту часть, которую вы хотите вывести, и оператор ^^ вверх по этой части. Захват спереди и сзади (совпадающий с. *), Чтобы воссоздать всю строку:

 foo=syslog_apr_24_30 if [[ $foo =~ (.*)(_[az])(.*) ]]; then foo=${BASH_REMATCH[1]}${BASH_REMATCH[2]^^}${BASH_REMATCH[3]} fi 

Если вы не помните все правила кавычек, можно указать все, кроме регулярного выражения (что сделало бы =~ выполнить буквальное совпадение строк).

Оператор ^ upcase-first работает только в начале переменной (или элемента массива). И, похоже, не существует расширения подстроки, которое дает вам то, что perl вызовет lvalue (которое вы можете назначить / изменить). Операторы up / downcase-first могут принимать шаблон, который сопоставляется по каждому символу, но это не помогает пропустить syslog_ , потому что есть месячные имена, начинающиеся с символов в «syslog».

В любом случае, это может быть быстрее, чем foo="$(echo "$foo" | sed 's/_./\U&/')" (опубликовано как комментарий к принятому ответу, Гленн Джекман).

Bash, sed или awk будут МНОГО раз быстрее, чем perl. Если вы начнете находить несколько Perl-одностроков, полезных в сценарии оболочки, вы должны просто написать все это в perl.

Если месяц всегда следует за первым «_» (подчеркиванием), используйте его (как показано в других ответах):

 sed -e 's/_\(.\)/_\u\1/' 

Если могут быть другие символы подчеркивания до того, что предшествует месяцу, то вышеуказанное не будет работать.

Если месяц всегда начинается с 8-го символа, используйте это:

 sed -e 's/^\(.\{7\}\)\(.\)/\1\u\2/'