文字列内の1文字のみを小文字/大文字にawkまたはsedしますか?


13

いくつかの文字列で1文字のみを大文字/小文字にする方法はありますか?

入力例:

syslog_apr_24_30
syslog_mar_01_17

望ましい出力:

syslog_Apr_24_30
syslog_Mar_01_17

月の大文字で始まることに注意してください。

私は試しましたawkが、それを機能させるのに十分ではありません。

回答:


18

\uGNU sedで使用して、大文字を使用できます。

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

Perlは同じことを行います:

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

\l 逆を行います。


8
よりシンプルなタッチ:sed 's/_./\U&/'
グレンジャックマン


3

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

3

を使用して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

3

Perlのアプローチは次のとおりです。

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

これ-pにより、で指定されたスクリプトを適用した後に各行が印刷され-eます。置換は、の最初のインスタンス_とそれに続く文字を($&一致したものは何でも)大文字(uc())でe置き換えs///eます。式を評価するには、置換演算子の最後に()が必要です。



1

正規表現を使用して、^^大文字に変換する部分とその部分の大文字変換演算子を選択する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ですべてを記述する必要があります。


0

月が常に最初の「_」(アンダースコア)の後に続く場合、これを使用します(他の回答に示されているように)。

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

月の前のアンダースコアに他のアンダースコアがある場合、上記は機能しません。

月が常に8番目の文字で始まる場合、これを使用します。

sed -e 's/^\(.\{7\}\)\(.\)/\1\u\2/'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.