Intereting Posts
Как создать файл, даже пользователь root не может его удалить Письма не отправляются в один конкретный домен каков эквивалент CentOS / var / log / syslog (на Ubuntu)? ls выводит несколько столбцов, даже если отправлен в grep с помощью zml-конфигурации grml Объединение двух переменных приводит их в действие в Windows Сила отправки писем на порт 587 Используется ли Unix бухгалтерами и другими не-программистами в AT & T в 70-х и 80-х годах? Не удалось запустить Gnome после отказа от файла-rc Не удается добавить пользователя в группу? как исправить EXT2-fs (sda1): ошибка: ext2_lookup удален inode, ссылка XXXX Как перевернуть ключи хоста ssh? Каков наилучший способ скопировать файлы из файловой системы ext3 в NTFS и сохранить права собственности и разрешения? трубопровод с недетерминированным выходом Могу ли я перейти на Gnome 3.4 на Debian, не могу войти в мой главный пользователь? Присоединение к сеансу Emacs

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/'