bash가있는 변수의 대문자 첫 문자


162

bash로 문자열의 첫 번째 문자 만 대문자로 바꾸고 싶습니다.

foo="bar";

//uppercase first character

echo $foo;

"Bar"를 인쇄해야합니다.


1
정확한 복제본은 아니지만 Bash 셸 스크립팅에서 문자열을 소문자변환에 설명 된 많은 기술 을이 문제에 적용 할 수도 있습니다.
pjh

답변:


148
foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"

2
최고 점수 답변보다 더 복잡하지만 실제로 이것은 '변수의 첫 번째 문자 대문자'와 정확히 일치합니다. 최고 점수의 답변에는 해당 결과가 없습니다. 간단한 답변이 올바른 답변보다 더 기꺼이 찬성되는 것 같습니까?
Krzysztof Jabłoński

15
@ KrzysztofJabłoński : 실제로, 아래의 "최고 점수 답변"은 Bash 4에서이 답변과 동일한 결과를 생성합니다.이 답변에는 서브 쉘 (또 다른 쉘) 호출의 오버 헤드, 'tr'유틸리티 호출 (다른 프로세스)의 오버 헤드가 있습니다. here-doc / string (임시 파일 생성)을 사용하는 오버 헤드이며 Bash가 아닌 최고 점수의 답변과 비교하여 두 가지 대체를 사용합니다. 레거시 코드를 작성해야하는 경우 서브 쉘 대신 함수 사용을 고려하십시오.
Steve

2
이 답변은 입력이 모두 소문자라고 가정합니다. 이 변형에는 가정이 없습니다 : $ (tr '[: lower :]' '[: upper :]'<<< $ {foo : 0 : 1}) $ (tr '[: upper :]' '[: lower : ] '<<< $ {foo : 1})
Itai Hanski

5
@ItaiHanski OP는 나머지 캐릭터들에게 일어날 일을 명시하지 않았다. 그들이로 바꾸고 싶다고 가정 notQuiteCamel했습니다 NotQuiteCamel. 서브 쉘과 tr 프로세스의 수를 두 배로 증가시키면서, 변종은 부작용을 일으키거나 나머지를 소문자로 강제합니다.
Jesse Chisholm

3
@DanieleOrlando, true, 그러나이 질문에는 이외의 태그가 없습니다 bash.
Charles Duffy

314

bash (버전 4 이상)를 사용하는 한 가지 방법 :

foo=bar
echo "${foo^}"

인쇄물:

Bar

2
이것과 반대되는 것이 있습니까?
CMCDragonkai

44
@CMCDragonkai : 첫 문자를 소문자로 사용하려면을 사용하십시오 "${foo,}". 모든 문자를 소문자로 사용하려면을 사용하십시오 "${foo,,}". 모든 문자를 대문자로하려면을 사용하십시오 "${foo^^}".
Steve

1
실수로 그 눈치 ${foo~}${foo~~}같은 효과를 가지고 ${foo^}${foo^^}. 그러나 나는 그 대안이 어디서나 언급되는 것을 보지 못했습니다.
mivk

5
이것은 Mac에서 작동하지 않는 것 같습니다. 다음과 같은 오류가 발생합니다 :bad substitution
Toland Hon

1
@TolandHon : 이미 해결 했으므로 버전 4.x로 업그레이드하거나 어떤 이유로 해당 시스템을 업그레이드 할 수없는 경우 다른 솔루션을 시도해야합니다.
Steve

29

한 가지 방법으로 sed:

echo "$(echo "$foo" | sed 's/.*/\u&/')"

인쇄물:

Bar

10
MacOS10 Lion sed에서 작동하지 않습니다. 한숨을 쉬면 \ u는 연산자 대신 u로 확장됩니다.
vwvan 2016 년

2
@vwvan brew install coreutils gnu-sed명령에 따라 접두사없이 명령을 사용하십시오 g. 가치가있는 것은 GNU 버전을 얻은 이후로 이러한 명령의 OSX 버전을 실행하고 싶지 않았습니다.
Dean

@vwvan : 예, 죄송합니다.이 경우 GNU가 필요 sed합니다
Steve

2
@Dean : FWIW, 저는 OSX를 실행하고 싶지 않았습니다 :-)
Steve

5
로 변경하면 sed 's/./\U&/POSIX sed에서 작동합니다.
David Conrad


14

다음은 "기본"텍스트 도구 방법입니다.

#!/bin/bash

string="abcd"
first=`echo $string|cut -c1|tr [a-z] [A-Z]`
second=`echo $string|cut -c2-`
echo $first$second

마지막으로 변수와 Mac에서 작동하는 것! 감사합니다!
OZZIE

4
@DanieleOrlando는 원하는만큼 휴대용이 아닙니다. 또는 범위에 tr [:lower:] [:upper:]속하지 않은 문자를 포함하는 언어 / 로케일에서 작동해야하는 경우 더 나은 선택 입니다. a-zA-Z
Charles Duffy

8

awk 만 사용

foo="uNcapItalizedstrIng"
echo $foo | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}'

결과 : Uncapitalizedstring
Alex Freshmann

4

bash-3.2를 사용하여 순수한 bash에서 수행 할 수 있습니다.

# First, get the first character.
fl=${foo:0:1}

# Safety check: it must be a letter :).
if [[ ${fl} == [a-z] ]]; then
    # Now, obtain its octal value using printf (builtin).
    ord=$(printf '%o' "'${fl}")

    # Fun fact: [a-z] maps onto 0141..0172. [A-Z] is 0101..0132.
    # We can use decimal '- 40' to get the expected result!
    ord=$(( ord - 40 ))

    # Finally, map the new value back to a character.
    fl=$(printf '%b' '\'${ord})
fi

echo "${fl}${foo:1}"

foo를 정의하는 방법? 시도 foo = $1했지만 난 단지 얻을-bash: foo: command not found
OZZIE

1
@OZZIE, =할당에 공백이 없습니다 . 이것은 shellcheck.net 이 프로그래밍 방식으로 찾을 수 있는 것입니다 .
Charles Duffy

나는 항상 쉘 스크립트에 대해 잊어 버린다. 한 공간 (이전 / 후)이 중요한 언어 만 ... 한숨 (정확히 기억하면 파이썬은 4 이상이다)
OZZIE

@OZZIE, 그것 가지고 는 중요하지 않았다, 당신은 통과 할 수 없기 때문에, 문제가하는 =프로그램에 인수로 (그것이 알고 생각하는 방법을 someprogram =실행 someprogram, 또는 명명 된 변수에 할당 someprogram?)
찰스 더피

3

이것도 작동합니다 ...

FooBar=baz

echo ${FooBar^^${FooBar:0:1}}

=> Baz
FooBar=baz

echo ${FooBar^^${FooBar:1:1}}

=> bAz
FooBar=baz

echo ${FooBar^^${FooBar:2:2}}

=> baZ

등등.

출처 :

소개 / 튜토리얼 :


3

첫 단어 만 대문자로 쓰려면 :

foo='one two three'
foo="${foo^}"
echo $foo

네 둘 셋


변수의 모든 단어 를 대문자로 바꾸려면 :

foo="one two three"
foo=( $foo ) # without quotes
foo="${foo[@]^}"
echo $foo

O NE T WO T의 HREE


(bash 4 이상에서 작동)


foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done) 모든 단어에 대한 짧은 해상도. foo는 지금은 "1 2 3"입니다
vr286

처음 3 ~ 4자를 대문자로 대문자로 바꾸려면 어떻게해야합니까? pqrs-123-v1 에서 PQRS-123-v1 처럼 ? 또는 첫 하이픈 앞에있는 모든 글자는 ...
Vicky Dev는

2

Linux 및 OSX 모두를위한 대체적이고 깨끗한 솔루션이며 bash 변수와 함께 사용할 수도 있습니다

python -c "print(\"abc\".capitalize())"

Abc를 반환


0

이것은 나를 위해 일했다 :

현재 디렉토리에서 모든 * php 파일을 검색하고 각 파일 이름의 첫 문자를 대문자로 바꿉니다.

예 : test.php => Test.php

for f in *php ; do mv "$f" "$(\sed 's/.*/\u&/' <<< "$f")" ; done

4
원래 질문은 문자열이었고 파일 이름 바꾸기에 대한 참조는 없었습니다.
AndySavage

0

여기에 재미를 위해 당신이 있습니다 :

foo="bar";    

echo $foo | awk '{$1=toupper(substr($1,0,1))substr($1,2)}1'
# or
echo ${foo^}
# or
echo $foo | head -c 1 | tr [a-z] [A-Z]; echo $foo | tail -c +2
# or
echo ${foo:1} | sed -e 's/^./\B&/'

0

정확히 무엇을 물어 보았지만 매우 도움이 됨

declare -u foo #When the variable is assigned a value, all lower-case characters are converted to upper-case.

foo=bar
echo $foo
BAR

그리고 그 반대

declare -l foo #When the variable is assigned a value, all upper-case characters are converted to lower-case.

foo=BAR
echo $foo
bar

-1
first-letter-to-lower () {
        str="" 
        space=" " 
        for i in $@
        do
                if [ -z $(echo $i | grep "the\|of\|with" ) ]
                then
                        str=$str"$(echo ${i:0:1} | tr  '[A-Z]' '[a-z]')${i:1}$space" 
                else
                        str=$str${i}$space 
                fi
        done
        echo $str
}
first-letter-to-upper-xc () {
        v-first-letter-to-upper | xclip -selection clipboard
}
first-letter-to-upper () {
        str="" 
        space=" " 
        for i in $@
        do
                if [ -z $(echo $i | grep "the\|of\|with" ) ]
                then
                        str=$str"$(echo ${i:0:1} | tr  '[a-z]' '[A-Z]')${i:1}$space" 
                else
                        str=$str${i}$space 
                fi
        done
        echo $str
}

첫 번째 문자부터 낮은 xc () {v 첫 번째 문자부터 낮은 | xclip-선택 클립 보드}


-7

첫 번째 문자 문자 가 아닌 경우 (탭, 공백 및 이스케이프 된 큰 따옴표)는 어떻게됩니까? 편지를 찾을 때까지 시험해 보는 것이 좋습니다 ! 그래서:

S='  \"ó foo bar\"'
N=0
until [[ ${S:$N:1} =~ [[:alpha:]] ]]; do N=$[$N+1]; done
#F=`echo ${S:$N:1} | tr [:lower:] [:upper:]`
#F=`echo ${S:$N:1} | sed -E -e 's/./\u&/'` #other option
F=`echo ${S:$N:1}
F=`echo ${F} #pure Bash solution to "upper"
echo "$F"${S:(($N+1))} #without garbage
echo '='${S:0:(($N))}"$F"${S:(($N+1))}'=' #garbage preserved

Foo bar
= \"Foo bar=

6
더 깨끗한 코드를 작성하십시오! 당신은 모든 곳에서 따옴표가 부족합니다 . 더 이상 사용되지 않는 구문 (백틱)을 사용하고 있습니다. 낡은 구문 ( $[...])을 사용하고 있습니다. 쓸모없는 괄호를 많이 사용하고 있습니다. 문자열이 라틴 알파벳의 문자로 구성되어 있다고 가정합니다 (강조 문자 또는 다른 알파벳의 문자는 어떻습니까?). 이 스 니펫을 사용하려면 많은 작업이 필요합니다! (정규식을 사용하고 있기 때문에 정규식을 사용하여 루프 대신 첫 번째 문자를 찾을 수도 있습니다).
gniourf_gniourf

6
당신이 틀렸다고 생각합니다. 공감대와 함께 답의 모든 잘못된 패턴과 오해를 설명하는 필수 의견입니다. 완고하지 말고 실수를 배우십시오 (그리고 그 전에 이해하려고 노력하십시오). 좋은 친구가되는 것은 나쁜 습관을 퍼뜨리는 것과도 양립 할 수 없습니다.
gniourf_gniourf

1
또는 Bash ≥4를 사용하는 경우 필요하지 않습니다 tr.if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
gniourf_gniourf

5
이 코드는 여전히 심각하게 손상되었습니다. 현대의 대체 구문 대신 여전히 백틱을 사용하고 있습니다. 여전히 타의 추종을 불허합니다. 그것들이 실제로 중요한 장소에는 여전히 따옴표가 없습니다 . 등. 누락 된 인용 부호가 차이가 있다고 생각하지 않으면 이 코드가 깨끗해질 때까지 shellcheck.net에서 찾은 문제를 수정하십시오 .
Charles Duffy

2
unix.stackexchange.com/questions/68694/… 에서 인용 한 언어 는 파서가 단어 목록을 기대하는echo $foo 상황의 예입니다 . 에서 의 내용 은 문자열 분할 및 glob-expanded입니다. 이것은 예제와 나머지 모두에 대해서도 마찬가지입니다 . BashPitfalls # 14를 참조하십시오 . echo ${F}Fecho ${S:$N:1}
Charles Duffy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.