回答:
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
正規表現を使用して、^^
大文字に変換する部分とその部分の大文字変換演算子を選択するPure Bash4.x。文字列全体を再作成するために、前面と背面にタック(。*で一致):
foo=syslog_apr_24_30
if [[ $foo =~ (.*)(_[a-z])(.*) ]]; then
foo=${BASH_REMATCH[1]}${BASH_REMATCH[2]^^}${BASH_REMATCH[3]}
fi
すべての引用ルールを覚えていない場合は、正規表現以外のすべてを引用しても安全です(これにより、 =~
リテラル文字列の一致を行います)。
の ^
UPCASE第オペレータが唯一の変数(または配列要素)の開始時に働きます。そして、perlが左辺値と呼ぶものを与える部分文字列展開はないようです(/ valueに割り当てることができます)。up / downcase-first演算子は、文字ごとに一致するパターンを取ることができますがsyslog_
、「syslog」の文字で始まる月の名前があるため、スキップすることはできません。
とにかく、これはより速いかもしれません foo="$(echo "$foo" | sed 's/_./\U&/')"
(グレン・ジャックマンによる受け入れられた答えへのコメントとして投稿された)。
Bash、sed、またはawkは、perlよりも何倍も高速になります。シェルスクリプトで便利な複数のperlワンライナーを見つけ始める場合は、perlですべてを記述する必要があります。
sed 's/_./\U&/'