문자열에서 한 문자 만 소문자 / 대문자로 awk 또는 sed?


13

일부 문자열에서 한 문자 만 대문자 / 소문자로 만드는 방법이 있습니까?

입력 예 :

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 -pe 's/_(.)/_\u$1/' input

\l 반대입니다.


8
터치 간단 :sed 's/_./\U&/'
글렌 잭맨

4

awk :

echo "syslog_apr_24_30" | 
  awk -F'_' '{print $1"_"toupper(substr($2,1,1)) substr($2,2)  "_"$3"_"$4}'

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()제 1,) e(대체 연산자의 끝에서 s///e) 식을 평가하기 위해 필요하다.


2

다른 perl:

perl -F_ -anle '$F[1] = ucfirst $F[1];print join "_", @F'

1

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 우선 연산자는 변수 (또는 배열 요소)의 시작 부분에서 작동한다. 그리고 펄이 lvalue라고 부르는 것을 제공하는 하위 문자열 확장이없는 것 같습니다 (할당 / 수정 가능). 대문자 / 소문자 우선 연산자는 문자별로 일치하는 패턴을 취할 수 있지만 syslog_"syslog"에서 문자로 시작하는 월 이름이 있기 때문에 건너 뛰는 데 도움이되지 않습니다 .

어쨌든, 이것은 foo="$(echo "$foo" | sed 's/_./\U&/')"글렌 잭맨 (Glenn Jackman의 대답에 대한 의견으로 게시 됨) 보다 빠를 수 있습니다 .

배쉬, sed 또는 awk는 perl보다 몇 배 빠릅니다. 쉘 스크립트에서 유용한 여러 개의 perl one-liner를 찾기 시작하면 모든 것을 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.