etc./StackOverFlow

Bash에서 문자열을 소문자로 변환하는 방법은 무엇입니까?

청렴결백한 만능 재주꾼 2022. 3. 17. 08:08
반응형

질문자 :assassin


에서 문자열을 소문자 문자열로 변환하는 방법이 있습니까?

예를 들어 다음과 같은 경우:

 a="Hi all"

다음으로 변환하고 싶습니다.

 "hi all"


다양한 방법이 있습니다.

POSIX 표준

트르

 $ echo "$a" | tr '[:upper:]' '[:lower:]' hi all

AWK

 $ echo "$a" | awk '{print tolower($0)}' hi all

비 POSIX

다음 예에서 이식성 문제가 발생할 수 있습니다.

배쉬 4.0

 $ echo "${a,,}" hi all

세드

 $ echo "$a" | sed -e 's/\(.*\)/\L\1/' hi all # this also works: $ sed -e 's/\(.*\)/\L\1/' <<< "$a" hi all

 $ echo "$a" | perl -ne 'print lc' hi all

세게 때리다

 lc(){ case "$1" in [AZ]) n=$(printf "%d" "'$1") n=$((n+32)) printf \\$(printf "%o" "$n") ;; *) printf "%s" "$1" ;; esac } word="I Love Bash" for((i=0;i<${#word};i++)) do ch="${word:$i:1}" lc "$ch" done

참고: 이것에 대한 YMMV. shopt -u nocasematch; 를 사용하더라도 저에게는 작동하지 않습니다(GNU bash 버전 4.2.46 및 4.0.33(동일한 동작 2.05b.0이지만 nocasematch는 구현되지 않음)). . nocasematch를 설정 해제하면 [[ "fooBaR" == "FOObar" ]]가 OK와 일치하지만 내부 대소문자가 이상하게 [bz]가 [AZ]와 잘못 일치합니다. Bash는 이중 부정("nocasematch 설정 해제")으로 인해 혼란스러워합니다! :-)


ghostdog74

배시 4:

소문자로

 $ string="A FEW WORDS" $ echo "${string,}" a FEW WORDS $ echo "${string,,}" a few words $ echo "${string,,[AEIUO]}" a FeW WoRDS $ string="A Few Words" $ declare -l string $ string=$string; echo "$string" a few words

대문자로

 $ string="a few words" $ echo "${string^}" A few words $ echo "${string^^}" A FEW WORDS $ echo "${string^^[aeiou]}" A fEw wOrds $ string="A Few Words" $ declare -u string $ string=$string; echo "$string" A FEW WORDS

토글(문서화되지 않았지만 컴파일 시 선택적으로 구성 가능)

 $ string="A Few Words" $ echo "${string~~}" a fEW wORDS $ string="A FEW WORDS" $ echo "${string~}" a FEW WORDS $ string="a few words" $ echo "${string~}" A few words

대문자 사용(문서화되지 않았지만 컴파일 시 선택적으로 구성 가능)

 $ string="a few words" $ declare -c string $ string=$string $ echo "$string" A few words

제목 케이스:

 $ string="a few words" $ string=($string) $ string="${string[@]^}" $ echo "$string" A Few Words $ declare -c string $ string=(a few words) $ echo "${string[@]}" A Few Words $ string="a FeW WOrdS" $ string=${string,,} $ string=${string~} $ echo "$string" A few words

declare 속성을 끄려면 + 사용하십시오. 예를 들어 declare +c string . 이는 현재 값이 아닌 후속 할당에 영향을 줍니다.

declare 옵션은 변수의 속성을 변경하지만 내용은 변경하지 않습니다. 내 예제의 재할당은 변경 사항을 표시하도록 내용을 업데이트합니다.

편집하다:

Ghostdog74에서 제안한 대로 "첫 글자를 단어로 전환"( ${var~} )을 추가했습니다.

편집: Bash 4.3과 일치하도록 물결표 동작을 수정했습니다.


Dennis Williamson

echo "Hi All" | tr "[:upper:]" "[:lower:]"

shuvalov

tr :

 a="$(tr [AZ] [az] <<< "$a")"

엉엉 :

 { print tolower($0) }

세드 :

 y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/

Ignacio Vazquez-Abrams

나는 이것이 오래된 게시물이라는 것을 알고 있지만 다른 사이트에 대해 이 답변을 만들었으므로 여기에 게시할 것이라고 생각했습니다.

UPPER -> lower : 파이썬 사용:

 b=`echo "print '$a'.lower()" | python`

또는 루비:

 b=`echo "print '$a'.downcase" | ruby`

또는 펄:

 b=`perl -e "print lc('$a');"`

또는 PHP:

 b=`php -r "print strtolower('$a');"`

또는 awk:

 b=`echo "$a" | awk '{ print tolower($1) }'`

또는 세드:

 b=`echo "$a" | sed 's/./\L&/g'`

또는 배쉬 4:

 b=${a,,}

또는 NodeJS:

 b=`node -p "\"$a\".toLowerCase()"`

dd 를 사용할 수도 있습니다.

 b=`echo "$a" | dd conv=lcase 2> /dev/null`

아래 -> 위 :

파이썬 사용:

 b=`echo "print '$a'.upper()" | python`

또는 루비:

 b=`echo "print '$a'.upcase" | ruby`

또는 펄:

 b=`perl -e "print uc('$a');"`

또는 PHP:

 b=`php -r "print strtoupper('$a');"`

또는 awk:

 b=`echo "$a" | awk '{ print toupper($1) }'`

또는 세드:

 b=`echo "$a" | sed 's/./\U&/g'`

또는 배쉬 4:

 b=${a^^}

또는 NodeJS:

 b=`node -p "\"$a\".toUpperCase()"`

dd 를 사용할 수도 있습니다.

 b=`echo "$a" | dd conv=ucase 2> /dev/null`

또한 'shell'이라고 말하면 bash zsh 를 사용할 수 있다면 다음과 같이 쉽습니다.

 b=$a:l

소문자 및

 b=$a:u

대문자의 경우.


nettux

zsh에서:

 echo $a:u

zsh를 사랑해야합니다!


Scott Smedley

GNU sed 사용:

 sed 's/.*/\L&/'

예시:

 $ foo="Some STRIng"; $ foo=$(echo "$foo" | sed 's/.*/\L&/') $ echo "$foo" some string

devnull

프리 배쉬 4.0

Bash 문자열의 대소문자를 낮추고 변수에 할당

 VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]') echo "$VARIABLE"

Community Wiki

Bash 5.1 L 매개변수 변환을 사용하여 이를 수행하는 직접적인 방법을 제공합니다.

 ${var@L}

예를 들어 다음과 같이 말할 수 있습니다.

 $ v="heLLo" $ echo "${v@L}" hello

U 대문자를 사용할 수도 있습니다.

 $ v="hello" $ echo "${v@U}" HELLO

그리고 첫 글자를 u 대문자로 만드세요.

 $ v="hello" $ echo "${v@u}" Hello

fedorqui 'SO stop harming'

당신은 이것을 시도 할 수 있습니다

 s="Hello World!" echo $s # Hello World! a=${s,,} echo $a # hello world! b=${s^^} echo $b # HELLO WORLD!

여기에 이미지 설명 입력

참조 : http://wiki.workassis.com/shell-script-convert-text-to-lowercase-and-uppercase/


Bikesh M

내장 기능만 사용하는 표준 셸(배시즘 없음)의 경우:

 uppers=ABCDEFGHIJKLMNOPQRSTUVWXYZ lowers=abcdefghijklmnopqrstuvwxyz lc(){ #usage: lc "SOME STRING" -> "some string" i=0 while ([ $i -lt ${#1} ]) do CUR=${1:$i:1} case $uppers in *$CUR*)CUR=${uppers%$CUR*};OUTPUT="${OUTPUT}${lowers:${#CUR}:1}";; *)OUTPUT="${OUTPUT}$CUR";; esac i=$((i+1)) done echo "${OUTPUT}" }

그리고 대문자의 경우:

 uc(){ #usage: uc "some string" -> "SOME STRING" i=0 while ([ $i -lt ${#1} ]) do CUR=${1:$i:1} case $lowers in *$CUR*)CUR=${lowers%$CUR*};OUTPUT="${OUTPUT}${uppers:${#CUR}:1}";; *)OUTPUT="${OUTPUT}$CUR";; esac i=$((i+1)) done echo "${OUTPUT}" }

technosaurus

bash 4에서는 조판을 사용할 수 있습니다

예시:

 A="HELLO WORLD" typeset -l A=$A

c4f4t0r

정규식

공유하고 싶은 명령을 인정하고 싶지만 사실은 http://commandlinefu.com 에서 직접 사용하기 위해 얻었습니다. cd 하면 모든 파일과 폴더가 재귀적으로 소문자로 변경된다는 이점이 있으므로 주의해서 사용하십시오. 이것은 훌륭한 명령줄 수정이며 드라이브에 저장한 수많은 앨범에 특히 유용합니다.

 find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

현재 디렉토리 또는 전체 경로를 나타내는 찾기 뒤에 점(.) 대신 디렉토리를 지정할 수 있습니다.

이 솔루션이 이 명령이 수행하지 않는 한 가지가 공백을 밑줄로 바꾸는 것이 유용하다는 것이 입증되기를 바랍니다.


Derek Shaw

대소문자 변환은 알파벳에 대해서만 수행됩니다. 따라서 이것은 깔끔하게 작동해야 합니다.

나는 대문자에서 소문자로 az 사이의 알파벳을 변환하는 데 집중하고 있습니다. 다른 문자는 그대로 stdout으로 인쇄해야 합니다...

az 범위 내의 path/to/file/filename에 있는 모든 텍스트를 AZ로 변환합니다.

소문자를 대문자로 변환하기 위해

 cat path/to/file/filename | tr 'az' 'AZ'

대문자에서 소문자로 변환하기 위해

 cat path/to/file/filename | tr 'AZ' 'az'

예를 들어,

파일 이름:

 my name is xyz

다음으로 변환됩니다.

 MY NAME IS XYZ

예 2:

 echo "my name is 123 karthik" | tr 'az' 'AZ' # Output: # MY NAME IS 123 KARTHIK

예 3:

 echo "my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'az' 'AZ' # Output: # MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK

theBuzzyCoder

간단한 방법

 echo "Hi all" | awk '{ print tolower($0); }'

Atul23

Bash 사용하지 않는 외부 프로그램을 사용하는 많은 답변.

Bash4를 사용할 수 있다는 것을 안다면 ${VAR,,} 표기법을 사용해야 합니다(쉽고 멋집니다). Bash 4 이전의 경우(My Mac은 여전히 Bash 3.2를 사용합니다). @ghostdog74 답변의 수정된 버전을 사용하여 더 이식 가능한 버전을 만들었습니다.

하나는 lowercase 'my STRING' 이라고 부르고 소문자 버전을 얻을 수 있습니다. 결과를 var로 설정하는 방법에 대한 주석을 읽었지만 문자열을 반환할 수 없기 때문에 Bash 인쇄하는 것이 최상의 솔루션입니다. var="$(lowercase $str)" 와 같이 캡처하기 쉽습니다.

작동 방식

printf 를 사용 adding 32 각 문자의 ASCII 정수 표현을 얻은 upper-to->lower 이면 lower-to->upper 이면 subtracting 32 입니다. 그런 다음 printf 다시 사용하여 숫자를 다시 char로 변환합니다. 'A' -to-> 'a' 에서 32자의 차이가 있습니다.

printf 를 사용하여 설명:

 $ printf "%d\n" "'a" 97 $ printf "%d\n" "'A" 65

97 - 65 = 32

그리고 이것은 예제가 있는 작업 버전입니다.
많은 내용을 설명하는 코드의 주석을 참고하세요.

 #!/bin/bash # lowerupper.sh # Prints the lowercase version of a char lowercaseChar(){ case "$1" in [AZ]) n=$(printf "%d" "'$1") n=$((n+32)) printf \\$(printf "%o" "$n") ;; *) printf "%s" "$1" ;; esac } # Prints the lowercase version of a sequence of strings lowercase() { word="$@" for((i=0;i<${#word};i++)); do ch="${word:$i:1}" lowercaseChar "$ch" done } # Prints the uppercase version of a char uppercaseChar(){ case "$1" in [az]) n=$(printf "%d" "'$1") n=$((n-32)) printf \\$(printf "%o" "$n") ;; *) printf "%s" "$1" ;; esac } # Prints the uppercase version of a sequence of strings uppercase() { word="$@" for((i=0;i<${#word};i++)); do ch="${word:$i:1}" uppercaseChar "$ch" done } # The functions will not add a new line, so use echo or # append it if you want a new line after printing # Printing stuff directly lowercase "I AM the Walrus!"$'\n' uppercase "I AM the Walrus!"$'\n' echo "----------" # Printing a var str="A StRing WITH mixed sTUFF!" lowercase "$str"$'\n' uppercase "$str"$'\n' echo "----------" # Not quoting the var should also work, # since we use "$@" inside the functions lowercase $str$'\n' uppercase $str$'\n' echo "----------" # Assigning to a var myLowerVar="$(lowercase $str)" myUpperVar="$(uppercase $str)" echo "myLowerVar: $myLowerVar" echo "myUpperVar: $myUpperVar" echo "----------" # You can even do stuff like if [[ 'option 2' = "$(lowercase 'OPTION 2')" ]]; then echo "Fine! All the same!" else echo "Ops! Not the same!" fi exit 0

그리고 이것을 실행한 후의 결과:

 $ ./lowerupper.sh i am the walrus! I AM THE WALRUS! ---------- a string with mixed stuff! A STRING WITH MIXED STUFF! ---------- a string with mixed stuff! A STRING WITH MIXED STUFF! ---------- myLowerVar: a string with mixed stuff! myUpperVar: A STRING WITH MIXED STUFF! ---------- Fine! All the same!

이것은 ASCII 문자에 대해서만 작동해야 합니다 .

나에게는 ASCII 문자만 전달할 것이라는 것을 알고 있기 때문에 괜찮습니다.
예를 들어 대소문자를 구분하지 않는 일부 CLI 옵션에 이것을 사용하고 있습니다.


Gus Neves

v4를 사용하는 경우 이것은 기본 제공됩니다 . 그렇지 않은 경우 여기에 간단하고 널리 적용할 수 있는 솔루션이 있습니다. 이 스레드에 대한 다른 답변(및 주석)은 아래 코드를 만드는 데 상당히 도움이 되었습니다.

 # Like echo, but converts to lowercase echolcase () { tr [:upper:] [:lower:] <<< "${*}" } # Takes one arg by reference (var name) and makes it lowercase lcase () { eval "${1}"=\'$(echo ${!1//\'/"'\''"} | tr [:upper:] [:lower:] )\' }

노트:

  • 수행: a="Hi All" 그리고 다음: lcase a 는 다음과 동일한 작업을 수행합니다. a=$( echolcase "Hi All" )
  • LCASE 함수에서 사용 ${!1//\'/"'\''"} 대신 ${!1} 문자열은 따옴표에도 작업이 가능합니다.

Stephen M. Harris

이것은 기본 Bash 기능(Bash 버전 <4.0 포함)을 사용하여 접근 방식을 최적화하는 JaredTS486 접근 방식의 훨씬 빠른 변형입니다.

소문자 및 대문자 변환 모두에 대해 작은 문자열(25자) 및 더 큰 문자열(445자)에 대해 이 접근 방식을 1,000번 반복했습니다. 테스트 문자열은 주로 소문자이므로 소문자로 변환하는 것이 일반적으로 대문자로 변환하는 것보다 빠릅니다.

내 접근 방식을 Bash 3.2와 호환되는 이 페이지의 여러 다른 답변과 비교했습니다. 내 접근 방식은 여기에 문서화된 대부분의 접근 방식보다 훨씬 더 성능이 tr 여러 경우에 tr보다 빠릅니다.

다음은 25자의 1,000회 반복에 대한 타이밍 결과입니다.

  • 소문자에 대한 접근 방식은 0.46초입니다. 대문자의 경우 0.96초
  • 소문자에 대한 Orwellophile의 접근 방식 에 대한 1.16초; 대문자의 경우 1.59초
  • tr 을 소문자로 변환하려면 3.67초, 대문자의 경우 3.81초
  • 소문자에 대한 고스트독74의 접근 을 위한 11.12s; 대문자의 경우 31.41초
  • 테크노 사우르스의 소문자 접근의 경우 26.25초; 대문자의 경우 26.21초
  • JaredTS486의 소문자 접근 방식의 경우 25.06초; 대문자의 경우 27.04초

445자의 1,000번 반복에 대한 타이밍 결과(Witter Bynner의 시 "The Robin"으로 구성):

  • 소문자에 대한 접근 방식의 경우 2초; 대문자의 경우 12초
  • tr 은 소문자로 4s; 대문자의 경우 4초
  • Orwellophile의 소문자 접근 방식은 20초입니다. 대문자의 경우 29
  • 소문자에 대한 ghostdog74의 접근을 위한 75초; 대문자의 경우 669입니다. 일치가 우세한 테스트와 실패가 우세한 테스트 사이의 성능 차이가 얼마나 극적인지 주목하는 것은 흥미롭습니다.
  • 테크노 사우루스의 소문자 접근을 위한 467; 대문자의 경우 449
  • JaredTS486의 소문자 접근 방식을 위한 660; 대문자의 경우 660입니다. 이 접근 방식이 Bash에서 연속적인 페이지 폴트(메모리 스와핑)를 생성했다는 점은 흥미롭습니다.

해결책:

 #!/bin/bash set -e set -u declare LCS="abcdefghijklmnopqrstuvwxyz" declare UCS="ABCDEFGHIJKLMNOPQRSTUVWXYZ" function lcase() { local TARGET="${1-}" local UCHAR='' local UOFFSET='' while [[ "${TARGET}" =~ ([AZ]) ]] do UCHAR="${BASH_REMATCH[1]}" UOFFSET="${UCS%%${UCHAR}*}" TARGET="${TARGET//${UCHAR}/${LCS:${#UOFFSET}:1}}" done echo -n "${TARGET}" } function ucase() { local TARGET="${1-}" local LCHAR='' local LOFFSET='' while [[ "${TARGET}" =~ ([az]) ]] do LCHAR="${BASH_REMATCH[1]}" LOFFSET="${LCS%%${LCHAR}*}" TARGET="${TARGET//${LCHAR}/${UCS:${#LOFFSET}:1}}" done echo -n "${TARGET}" }

접근 방식은 간단합니다. 입력 문자열에 남아 있는 대문자가 있는 동안 다음 문자를 찾아 해당 문자의 모든 인스턴스를 소문자 변형으로 바꿉니다. 모든 대문자가 바뀔 때까지 반복합니다.

내 솔루션의 일부 성능 특성:

  1. 새 프로세스에서 외부 바이너리 유틸리티를 호출하는 오버헤드를 방지하는 쉘 내장 유틸리티만 사용합니다.
  2. 성능 저하를 초래하는 하위 쉘을 피합니다.
  3. 변수 내 전역 문자열 대체, 변수 접미사 트리밍, 정규식 검색 및 일치와 같이 성능을 위해 컴파일되고 최적화된 셸 메커니즘을 사용합니다. 이러한 메커니즘은 문자열을 통해 수동으로 반복하는 것보다 훨씬 빠릅니다.
  4. 변환할 고유한 일치 문자 수에 필요한 횟수만 반복합니다. 예를 들어, 3개의 다른 대문자가 있는 문자열을 소문자로 변환하려면 3번의 루프 반복만 필요합니다. 사전 구성된 ASCII 알파벳의 경우 최대 루프 반복 횟수는 26입니다.
  5. UCSLCS 는 추가 문자로 보강될 수 있습니다.

Dejay Clayton

Bash 4.0 이전 버전의 경우 이 버전이 가장 빨라야 합니다(명령을 분기/실행하지 않기 때문에).

 function string.monolithic.tolower { local __word=$1 local __len=${#__word} local __char local __octal local __decimal local __result for (( i=0; i<__len; i++ )) do __char=${__word:$i:1} case "$__char" in [AZ] ) printf -v __decimal '%d' "'$__char" printf -v __octal '%03o' $(( $__decimal ^ 0x20 )) printf -v __char \\$__octal ;; esac __result+="$__char" done REPLY="$__result" }

technosaurus의 대답 에도 가능성이 있었지만 제대로 실행되었습니다.


Orwellophile

이 질문이 얼마나 오래 되었고 technosaurus의 이 답변 과 유사함에도 불구하고 . 대부분의 플랫폼(내가 사용하는)과 bash의 이전 버전에서 이식 가능한 솔루션을 찾는 데 어려움을 겪었습니다. 나는 또한 배열, 함수 및 사소한 변수를 검색하기 위한 인쇄물, 에코 및 임시 파일 사용에 불만을 가지고 있습니다. 이것은 내가 공유할 것이라고 생각한 지금까지 저에게 아주 잘 작동합니다. 내 주요 테스트 환경은 다음과 같습니다.

  1. GNU bash, 버전 4.1.2(1)-릴리스(x86_64-redhat-linux-gnu)
  2. GNU bash, 버전 3.2.57(1)-릴리스(sparc-sun-solaris2.10)
 lcs="abcdefghijklmnopqrstuvwxyz" ucs="ABCDEFGHIJKLMNOPQRSTUVWXYZ" input="Change Me To All Capitals" for (( i=0; i<"${#input}"; i++ )) ; do : for (( j=0; j<"${#lcs}"; j++ )) ; do : if [[ "${input:$i:1}" == "${lcs:$j:1}" ]] ; then input="${input/${input:$i:1}/${ucs:$j:1}}" fi done done

문자열을 반복하는 간단한 C 스타일 for 루프. 이전에 이와 같은 것을 본 적이 없다면 아래 줄에 대해 내가 이것을 배웠습니다 . 이 경우 행은 char ${input:$i:1}(소문자)가 입력에 존재하는지 확인하고 있으면 이를 주어진 char ${ucs:$j:1}(대문자)로 대체하고 저장합니다. 다시 입력으로.

 input="${input/${input:$i:1}/${ucs:$j:1}}"

JaredTS486

변환된 문자열을 변수에 저장합니다. 다음은 나를 위해 일했습니다 - $SOURCE_NAME 에서 $TARGET_NAME

 TARGET_NAME="`echo $SOURCE_NAME | tr '[:upper:]' '[:lower:]'`"

nitinr708

Dejay Clayton의 우수한 솔루션을 기반으로 대문자/소문자를 전치 함수로 일반화하고(독립적으로 유용함), 결과를 변수에 반환하고(더 빠르고/안전하게) BASH v4+ 최적화를 추가했습니다.

 pkg::transpose() { # <retvar> <string> <from> <to> local __r=$2 __m __p while [[ ${__r} =~ ([$3]) ]]; do __m="${BASH_REMATCH[1]}"; __p="${3%${__m}*}" __r="${__r//${__m}/${4:${#__p}:1}}" done printf -v "$1" "%s" "${__r}" } pkg::lowercase() { # <retvar> <string> if (( BASH_VERSINFO[0] >= 4 )); then printf -v "$1" "%s" "${2,,}" else pkg::transpose "$1" "$2" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "abcdefghijklmnopqrstuvwxyz" fi } pkg::uppercase() { # <retvar> <string> if (( BASH_VERSINFO[0] >= 4 )); then printf -v "$1" "%s" "${2^^}" else pkg::transpose "$1" "$2" "abcdefghijklmnopqrstuvwxyz" \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" fi }

일을 단순하게 유지하기 위해 set -e 지원(또는 실제로 오류 검사)을 추가하지 않았습니다... 그렇지 않으면 일반적으로 shellguide를 따르고 pkg::transpose() printf -v 대한 가능한 변수 이름 충돌을 피하려고 시도합니다.


Scott Shambarger

출처 : http:www.stackoverflow.com/questions/2264428/how-to-convert-a-string-to-lower-case-in-bash

반응형