Yanıtlar:
echo "syslog_apr_24_30" |
awk -F'_' '{print $1"_"toupper(substr($2,1,1)) substr($2,2) "_"$3"_"$4}'
Awk alt dizeleri ve toupper ile sürüm
awk 'BEGIN{ FS=OFS="_"} {
cap=toupper(substr($2,1,1));
lower=substr($2,2,3);
$2 = cap lower; print
}' list.txt
Örnek çalışma:
$ 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
Kullanma awk:
awk -F_ '{
printf "%s_%s_%s_%s",$1,toupper(substr($2,1,1))substr($2,2,2),$3,$4"\n"
}' foo
veya
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
Misal
% 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
İşte bir Perl yaklaşımı:
$ perl -pe 's/_./uc($&)/e' file
syslog_Apr_24_30
syslog_Mar_01_17
-pTarafından verilen komut uygulandıktan sonra baskılı her satırı neden olur -e. İkame ilk örneğinin _ve onu izleyen karakterin kendisiyle ( $&eşleştirilen her şeydir ) üst kasanın ( uc()) eyerini alır s///e. İfadeleri değerlendirmek için ikame operatörünün ( ) sonunda gereklidir.
Pure Bash 4.x, üstlenmek istediğiniz parçayı seçmek için bir normal ifade ve o ^^bölümdeki üstteki işleci kullanarak. Tüm dizeyi yeniden oluşturmak için ön ve arkada (. * İle eşleştirilir) birleştirme:
foo=syslog_apr_24_30
if [[ $foo =~ (.*)(_[a-z])(.*) ]]; then
foo=${BASH_REMATCH[1]}${BASH_REMATCH[2]^^}${BASH_REMATCH[3]}
fi
Tüm alıntı kurallarını hatırlamıyorsanız, normal ifade hariç her şeyi alıntılamak güvenlidir (bu da =~gerçek bir dize eşleşmesi yapar).
İlk büyük ^harf operatörü yalnızca bir değişkenin (veya dizi öğesinin) başında çalışır. Ve perl'in lvalue olarak adlandırdığı (atamak / değiştirmek için atayabileceğiniz) herhangi bir alt dize genişletmesi yok gibi görünüyor. İlk / yukarı küçük harf işleçleri, karakter başına esasına göre bir desen alabilir, ancak atlamaya yardımcı olmaz syslog_, çünkü "syslog" da karakterlerle başlayan ay adları vardır.
Her neyse, bu daha hızlı olabilir foo="$(echo "$foo" | sed 's/_./\U&/')"(kabul edilen cevaba yorum olarak Glenn Jackman tarafından gönderildi).
Bash, sed veya awk perl'den çok daha hızlı olacaktır. Bir kabuk betiğinde birden çok perl tek katmanı bulmaya başlarsanız, her şeyi perl'e yazmanız gerekir.
Ay her zaman ilk "_" (alt çizgiyi) izliyorsa, bunu kullanın (diğer yanıtlarda gösterildiği gibi):
sed -e 's/_\(.\)/_\u\1/'
Ayın öncesinden önce başka alt çizgiler varsa, yukarıdaki çalışmaz.
Ay her zaman 8. karakterle başlıyorsa, bunu kullanın:
sed -e 's/^\(.\{7\}\)\(.\)/\1\u\2/'
sed 's/_./\U&/'