답변:
다양한 방법이 있습니다 :
$ echo "$a" | tr '[:upper:]' '[:lower:]'
hi all
$ echo "$a" | awk '{print tolower($0)}'
hi all
다음 예제에서 이식성 문제가 발생할 수 있습니다.
$ 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
[A-Z])
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. 를 사용하더라도 (GNU bash 버전 4.2.46 및 4.0.33 (및 동일한 동작 2.05b.0이지만 대소 문자 일치는 구현되지 않음)) 작동하지 않습니다 shopt -u nocasematch;
. nocasematch를 설정하지 않으면 [[ "fooBaR"== "FOObar"]]가 OK BUT과 일치하지만 이상하게도 [bz]가 [AZ]와 잘못 일치합니다. 배쉬는 이중 부정 ( "unset nocasematch")에 의해 혼동된다! :-)
word="Hi All"
다른 예제처럼, 그것은 반환 ha
하지 hi all
. 대문자로만 작동하며 이미 소문자로 된 문자는 건너 뜁니다.
tr
및 awk
예제 만 지정되어 있습니다.
tr '[:upper:]' '[:lower:]'
현재 로케일을 사용하여 대문자 / 소문자 등가를 판별하므로 분음 부호가있는 문자를 사용하는 로케일에서 작동합니다.
b="$(echo $a | tr '[A-Z]' '[a-z]')"
배쉬 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과 일치하도록 물결표 동작이 수정되었습니다.
string="łódź"; echo ${string~~}
하지만 echo ${string^^}
"ŁÓDŹ"는 반환 하지만 "łóDź"는 반환합니다. 에서도 LC_ALL=pl_PL.utf-8
. bash 4.2.24를 사용하고 있습니다.
en_US.UTF-8
. 버그이며 신고했습니다.
echo "$string" | tr '[:lower:]' '[:upper:]'
. 아마도 같은 실패를 보일 것입니다. 따라서 문제는 적어도 부분적으로 Bash가 아닙니다.
echo "Hi All" | tr "[:upper:]" "[:lower:]"
tr
이외의 문자에는 작동하지 않습니다. 올바른 로케일 세트와 로케일 파일이 생성되었습니다. 내가 뭘 잘못하고 있는지 알 수 있습니까?
[:upper:]
필요한가요?
a="$(tr [A-Z] [a-z] <<< "$a")"
{ print tolower($0) }
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
a="$(tr [A-Z] [a-z] <<< "$a")"
이 가장 쉬워 보입니다. 나는 ... 아직 초보
sed
해결책을 강력히 추천합니다 . 나는 어떤 이유로없는 환경에서 일하고 tr
있지만 아직없는 시스템을 찾지 못했습니다 sed
. 더 많은 시간을 보내고 싶습니다. sed
어쨌든 다른 일을 했으므로 체인을 만들 수 있습니다. 명령을 하나의 긴 문으로 묶습니다.
tr [A-Z] [a-z] A
단일 문자로 구성된 파일 이름이 있거나 nullgob 이 설정된 경우 셸에서 파일 이름 확장을 수행 할 수 있습니다 . tr "[A-Z]" "[a-z]" A
제대로 작동합니다.
sed
tr [A-Z] [a-z]
거의 모든 로케일에서 올바르지 않습니다. 예를 들어 en-US
로케일에서 A-Z
실제로 interval AaBbCcDdEeFfGgHh...XxYyZ
입니다.
나는 이것이 오래된 게시물이라는 것을 알고 있지만 다른 사이트에 대해이 답변을 만들었으므로 여기에 게시 할 것이라고 생각했습니다.
상단-> 하단 : 파이썬 사용 :
b=`echo "print '$a'.lower()" | python`
또는 루비 :
b=`echo "print '$a'.downcase" | ruby`
또는 Perl (아마 내가 가장 좋아하는 것) :
b=`perl -e "print lc('$a');"`
또는 PHP :
b=`php -r "print strtolower('$a');"`
또는 Awk :
b=`echo "$a" | awk '{ print tolower($1) }'`
또는 Sed :
b=`echo "$a" | sed 's/./\L&/g'`
또는 배쉬 4 :
b=${a,,}
또는 NodeJS가 있다면 (그리고 약간 견고합니다 ...)
b=`echo "console.log('$a'.toLowerCase());" | node`
당신은 또한 사용할 수 있습니다 dd
(그러나 나는하지 않을 것입니다!) :
b=`echo "$a" | dd conv=lcase 2> /dev/null`
하한-> 상한 :
파이썬을 사용하십시오 :
b=`echo "print '$a'.upper()" | python`
또는 루비 :
b=`echo "print '$a'.upcase" | ruby`
또는 Perl (아마 내가 가장 좋아하는 것) :
b=`perl -e "print uc('$a');"`
또는 PHP :
b=`php -r "print strtoupper('$a');"`
또는 Awk :
b=`echo "$a" | awk '{ print toupper($1) }'`
또는 Sed :
b=`echo "$a" | sed 's/./\U&/g'`
또는 배쉬 4 :
b=${a^^}
또는 NodeJS가 있다면 (그리고 약간 견고합니다 ...)
b=`echo "console.log('$a'.toUpperCase());" | node`
당신은 또한 사용할 수 있습니다 dd
(그러나 나는하지 않을 것입니다!) :
b=`echo "$a" | dd conv=ucase 2> /dev/null`
또한 'shell'이라고 말할 때 나는 당신이 의미한다고 가정하고 bash
있지만 당신이 zsh
그것을 사용할 수 있다면 그것은 쉽다
b=$a:l
소문자 및
b=$a:u
대문자.
a
작은 따옴표 가 포함 된 경우 동작이 깨졌을뿐 아니라 심각한 보안 문제가 발생한 것입니다.
zsh에서 :
echo $a:u
zsh를 사랑해야합니다!
echo ${(C)a} #Upcase the first char only
프리 배쉬 4.0
Bash 문자열의 대소 문자를 낮추고 변수에 할당
VARIABLE=$(echo "$VARIABLE" | tr '[:upper:]' '[:lower:]')
echo "$VARIABLE"
echo
파이프 필요 없음 : 사용$(tr '[:upper:]' '[:lower:]' <<<"$VARIABLE")
내장 만 사용하는 표준 쉘 (bashisms 없음)의 경우 :
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}"
}
${var:1:1}
은 Bashism입니다.
당신은 이것을 시도 할 수 있습니다
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/
공유하고 싶은 명령에 대해 신용을 얻고 싶지만 사실은 http://commandlinefu.com 에서 본인이 사용하기 위해 얻은 것입니다 . 그것은 장점을 가지고 당신의 경우 cd
는 재귀를 소문자주의하여 사용하시기 바랍니다 모든 파일과 폴더를 변경할 것입니다 자신의 홈 폴더 내의 디렉토리로 이동합니다. 그것은 훌륭한 명령 줄 수정이며 특히 드라이브에 저장된 여러 앨범에 유용합니다.
find . -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
find 다음에 현재 디렉토리 또는 전체 경로를 나타내는 dot (.) 대신 디렉토리를 지정할 수 있습니다.
이 솔루션 이이 명령이 수행하지 않는 한 가지 유용한 방법은 공백을 밑줄로 바꾸는 것입니다.
prename
에서 perl
: dpkg -S "$(readlink -e /usr/bin/rename)"
제공perl: /usr/bin/prename
실제로 사용하지 않는 외부 프로그램을 사용하는 많은 답변 Bash
.
Bash4를 사용할 수 있다는 것을 알고 있다면 실제로 ${VAR,,}
표기법을 사용해야합니다 (쉽고 시원합니다). Bash before 4 이전의 경우 (My Mac은 여전히 Bash 3.2를 사용합니다). 더 나은 버전을 만들기 위해 수정 된 @ ghostdog74 답변 버전을 사용했습니다.
하나는 당신이 전화를 lowercase 'my STRING'
하고 소문자 버전을 얻을 수 있습니다 . 결과를 var로 설정하는 것에 대한 의견을 읽었지만 Bash
문자열을 반환 할 수 없으므로 실제로 이식 할 수는 없습니다. 인쇄하는 것이 가장 좋습니다. 같은 것으로 쉽게 캡처 할 수 var="$(lowercase $str)"
있습니다.
작동 원리
이것이 작동하는 방식은 각 문자의 ASCII 정수 표현 printf
을 adding 32
if 와 if upper-to->lower
또는 subtracting 32
if 로 얻는 것 lower-to->upper
입니다. 그런 다음 printf
다시 사용 하여 숫자를 다시 문자로 변환하십시오. 에서 '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
[A-Z])
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
[a-z])
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 옵션에 이것을 사용하고 있습니다.
대소 문자 변환은 알파벳에 대해서만 수행됩니다. 따라서 이것은 깔끔하게 작동해야합니다.
az 사이의 알파벳을 대문자에서 소문자로 변환하는 데 중점을 둡니다. 다른 문자는 그대로 stdout으로 인쇄해야합니다 ...
az 범위 내의 path / to / file / filename에있는 모든 텍스트를 AZ로 변환
소문자를 대문자로 변환
cat path/to/file/filename | tr 'a-z' 'A-Z'
대문자에서 소문자로 변환
cat path/to/file/filename | tr 'A-Z' 'a-z'
예를 들어
파일 이름:
my name is xyz
로 변환됩니다 :
MY NAME IS XYZ
예 2 :
echo "my name is 123 karthik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 KARTHIK
예 3 :
echo "my name is 123 &&^&& #@$#@%%& kAR2~thik" | tr 'a-z' 'A-Z'
# Output:
# MY NAME IS 123 &&^&& #@0@%%& KAR2~THIK
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" )
${!1//\'/"'\''"}
대신을 ${!1}
사용하면 문자열에 따옴표가 있어도 작동합니다.4.0 이전의 Bash 버전의 경우이 버전이 가장 빠릅니다 ( 명령을 포크 / 실행 하지 않으므로 ).
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
[A-Z] )
printf -v __decimal '%d' "'$__char"
printf -v __octal '%03o' $(( $__decimal ^ 0x20 ))
printf -v __char \\$__octal
;;
esac
__result+="$__char"
done
REPLY="$__result"
}
technosaurus의 대답 은 잠재력이 있었지만 나에게 제대로 실행되었습니다.
이 질문은 몇 살이었지만 technosaurus의 답변 과 비슷합니다 . 구식 버전의 bash뿐만 아니라 대부분의 플랫폼 (이것은 내가 사용하는)에서 이식 가능한 솔루션을 찾는 데 어려움을 겪었습니다. 또한 배열, 함수 및 인쇄, 반향 및 임시 파일을 사용하여 사소한 변수를 검색하는 데 좌절했습니다. 이것은 내가 공유 할 것이라고 생각한 지금까지 매우 잘 작동합니다. 내 주요 테스트 환경은 다음과 같습니다.
- GNU bash, 버전 4.1.2 (1)-릴리스 (x86_64-redhat-linux-gnu)
- 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}}"
이는 기본 Bash 기능 (Bash 버전 <4.0 포함)을 사용하여 자신의 접근 방식을 최적화하는 JaredTS486 접근 방식의 훨씬 빠른 변형입니다 .
소문자와 대문자 변환 모두에서 작은 문자열 (25 자)과 큰 문자열 (445 자)에 대해이 방법을 1,000 회 반복했습니다. 테스트 문자열은 주로 소문자이므로 소문자로의 변환은 일반적으로 대문자보다 빠릅니다.
이 페이지에서 Bash 3.2와 호환되는 다른 답변과 내 접근 방식을 비교했습니다. 내 접근 방식은 여기에 설명 된 대부분의 접근 방식보다 훨씬 성능이 뛰어나며 tr
여러 경우 보다 훨씬 빠릅니다 .
다음은 25 개의 문자를 1,000 회 반복 한 타이밍 결과입니다.
tr
소문자 3.67s ; 대문자 3.81s445 자 (1000 번 반복)의 타이밍 결과 (Witter Bynner의 "The Robin"시 구성) :
tr
소문자를 위한 4s ; 대문자의 경우 4 초해결책:
#!/bin/bash
set -e
set -u
declare LCS="abcdefghijklmnopqrstuvwxyz"
declare UCS="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
function lcase()
{
local TARGET="${1-}"
local UCHAR=''
local UOFFSET=''
while [[ "${TARGET}" =~ ([A-Z]) ]]
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}" =~ ([a-z]) ]]
do
LCHAR="${BASH_REMATCH[1]}"
LOFFSET="${LCS%%${LCHAR}*}"
TARGET="${TARGET//${LCHAR}/${UCS:${#LOFFSET}:1}}"
done
echo -n "${TARGET}"
}
접근 방식은 간단합니다. 입력 문자열에 나머지 대문자가 있으면 다음 문자를 찾아 해당 문자의 모든 인스턴스를 소문자 변형으로 바꿉니다. 모든 대문자가 바뀔 때까지 반복하십시오.
내 솔루션의 일부 성능 특성 :
UCS
및 LCS
추가 문자로 확장 될 수 있습니다