Відповіді:
echo "syslog_apr_24_30" |
awk -F'_' '{print $1"_"toupper(substr($2,1,1)) substr($2,2) "_"$3"_"$4}'
Awk
версія з підрядками та тупером
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()
), e
в кінці оператора підстановки ( s///e
) потрібен для оцінки виразів.
Pure Bash 4.x, використовуючи регулярний вираз, щоб вибрати частину, яку ви хочете змінити, і ^^
оператора набірних матеріалів на цій частині. Натискання спереду та ззаду (відповідність. *) Для відновлення цілого рядка:
foo=syslog_apr_24_30
if [[ $foo =~ (.*)(_[a-z])(.*) ]]; then
foo=${BASH_REMATCH[1]}${BASH_REMATCH[2]^^}${BASH_REMATCH[3]}
fi
Якщо ви не пам’ятаєте всіх правил цитування, сміливо цитувати все, крім регулярного виразу (що дозволило б =~
виконати буквальну відповідність рядків).
Оператор ^
upcase-first працює лише на початку змінної (або елемента масиву). І, здається, немає розширення підрядків, яке дає вам те, що perl буде називати lvalue (яке ви можете призначити / змінити). Оператори "up / downcase" можуть приймати шаблон, який відповідає по символам, але це не допомагає пропустити 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/'
sed 's/_./\U&/'