bash의 문자열 길이


428

변수에 저장된 문자열의 길이를 어떻게 다른 변수에 할당합니까?

myvar="some string"
echo ${#myvar}  
# 11

다른 변수를 출력으로 11어떻게 설정 합니까?

답변:


270

UTF-8 문자열 길이

fedorqui의 정답 외에도 문자열 길이와 바이트 길이의 차이를 보여주고 싶습니다.

myvar='Généralités'
chrlen=${#myvar}
oLang=$LANG oLcAll=$LC_ALL
LANG=C LC_ALL=C
bytlen=${#myvar}
LANG=$oLang LC_ALL=$oLcAll
printf "%s is %d char len, but %d bytes len.\n" "${myvar}" $chrlen $bytlen

렌더링합니다 :

Généralités is 11 char len, but 14 bytes len.

저장된 문자를 볼 수도 있습니다.

myvar='Généralités'
chrlen=${#myvar}
oLang=$LANG oLcAll=$LC_ALL
LANG=C LC_ALL=C
bytlen=${#myvar}
printf -v myreal "%q" "$myvar"
LANG=$oLang LC_ALL=$oLcAll
printf "%s has %d chars, %d bytes: (%s).\n" "${myvar}" $chrlen $bytlen "$myreal"

대답합니다 :

Généralités has 11 chars, 14 bytes: ($'G\303\251n\303\251ralit\303\251s').

참고 : Isabell Cowan의 의견 에 따르면에 설정을 추가 $LC_ALL했습니다 $LANG.

인수의 길이

인수는 일반 변수와 동일하게 작동

strLen() {
    local bytlen sreal oLang=$LANG oLcAll=$LC_ALL
    LANG=C LC_ALL=C
    bytlen=${#1}
    printf -v sreal %q "$1"
    LANG=$oLang LC_ALL=$oLcAll
    printf "String '%s' is %d bytes, but %d chars len: %s.\n" "$1" $bytlen ${#1} "$sreal"
}

로 작동합니다

strLen théorème
String 'théorème' is 10 bytes, but 8 chars len: $'th\303\251or\303\250me'

유용한 printf수정 도구 :

만약 너라면:

for string in Généralités Language Théorème Février  "Left: ←" "Yin Yang ☯";do
    printf " - %-14s is %2d char length\n" "'$string'"  ${#string}
done

 - 'Généralités' is 11 char length
 - 'Language'     is  8 char length
 - 'Théorème'   is  8 char length
 - 'Février'     is  7 char length
 - 'Left: ←'    is  7 char length
 - 'Yin Yang ☯' is 10 char length

정말 예쁘지 않습니다 ... 이것에는 약간의 기능이 있습니다.

strU8DiffLen () { 
    local bytlen oLang=$LANG oLcAll=$LC_ALL
    LANG=C LC_ALL=C
    bytlen=${#1}
    LANG=$oLang LC_ALL=$oLcAll
    return $(( bytlen - ${#1} ))
}

그런 다음 :

for string in Généralités Language Théorème Février  "Left: ←" "Yin Yang ☯";do
    strU8DiffLen "$string"
    printf " - %-$((14+$?))s is %2d chars length, but uses %2d bytes\n" \
        "'$string'" ${#string} $((${#string}+$?))
  done 

 - 'Généralités'  is 11 chars length, but uses 14 bytes
 - 'Language'     is  8 chars length, but uses  8 bytes
 - 'Théorème'     is  8 chars length, but uses 10 bytes
 - 'Février'      is  7 chars length, but uses  8 bytes
 - 'Left: ←'      is  7 chars length, but uses  9 bytes
 - 'Yin Yang ☯'   is 10 chars length, but uses 12 bytes

불행히도 이것은 완벽하지 않습니다!

그러나 이중 간격 문자, 0 간격 문자, 역 변위 및 기타 단순하지 않은 이상한 UTF-8 동작이 남아 있습니다 ...

더 많은 제한 사항 은 diffU8test.sh 또는 diffU8test.sh.txt 를 참조하십시오.


파일 시스템은 문자가 아닌 바이트로 이름 제한을 부과 하므로이 답변에 감사드립니다.
Gid

1
LC_ALL = C 등을 설정해야 할 수도 있습니다.
Isabell Cowan

1
@ F.Hauri 그러나 일부 시스템에서는 LC_ALL을 단독으로 남겨두기 때문에 솔루션이 작동하지 않을 것입니다. 데비안의 기본 설치와 파생 제품에서는 제대로 작동하지만 Arch Linux와 같은 다른 시스템에서는 문자열의 정확한 바이트 길이를 제공하지 못합니다.
Isabell Cowan

1
간단하고 복잡한 것을 가져 주셔서 감사합니다 :)
thistleknot

2
@thistleknot 미안합니다, 對 간단히 때로는 단순한 아이디어 일뿐입니다.
F. Hauri

474

변수에 저장된 문자열의 길이를 얻으려면 다음과 같이하십시오.

myvar="some string"
size=${#myvar} 

제대로 저장되었는지 확인하려면 다음을 수행 echo하십시오.

$ echo "$size"
11

8
UTF-8 스팅을 사용하면 문자열 길이 바이트 길이를 가질 수 있습니다 . 내 답변보기
F. Hauri

다른 매개 변수 확장에서 직접 사용할 수도 있습니다. 예를 $rulename$RULE_PREFIX[ "${rulename:0:${#RULE_PREFIX}}" == "$RULE_PREFIX" ]
들어이

당신은 조금에게의 표현 설명해 주시겠습니까 #myvar{#myvar}?
Lerner Zhang

1
@lerneradams는 Bash 참조 매뉴얼을 참조 하십시오 → 3.5.3 Shell Parameter Expansion on ${#parameter}: 확장parameter 값의 문자 길이는 대체 됩니다.
fedorqui 'SO 중지 피해'10

25

당신이 사용할 수있는:

MYSTRING="abc123"
MYLENGTH=$(printf "%s" "$MYSTRING" | wc -c)
  • wc -c또는 wc --bytes바이트 수 = 유니 코드 문자는 2, 3 개 이상의 바이트로 계산됩니다.
  • wc -m또는 wc --chars문자 수 = 유니 코드 문자는 더 많은 바이트를 사용할 때까지 단일 문자로 계산됩니다.


3
진심이야? 파이프, 서브 쉘 및 사소한 것에 대한 외부 명령?
gniourf_gniourf

이것은 mylen=$(printf "%s" "$HOME/.ssh" | wc -c)수용 된 솔루션이 실패하고 먼저 해야하는 것과 같은 것을 처리합니다 myvar=$HOME/.ssh.
JL Peyret

23

가장 간단한 경우를 원했고 결과는 다음과 같습니다.

echo -n 'Tell me the length of this sentence.' | wc -m;
36

4
죄송합니다 메이트 :( 이것은 강타입니다 ... 손톱, 특히 엄지 손가락으로 모든 것을 보는 저주받은 망치. '이 문장의 길이를 말해주세요.'에는 36자가 포함되어 있습니다. echo '' | wc -m=> 1. 사용해야합니다 -n: echo -n '' | wc -m=> 0... 그렇다면 좋은 솔루션입니다 :)
AJP

1
정정 주셔서 감사합니다! 매뉴얼 페이지 말한다 : -n do not output the trailing newline
dmatej

17

이것을 명령 행 또는 함수 인수와 함께 사용하려면 size=${#1}대신 대신 사용하십시오 size=${#$1}. 두 번째는 더 본능적이지만 잘못된 구문입니다.


14
"<잘못된 구문>을 수행 할 수 없습니다"라는 문제의 일부는 해당 구문이 유효하지 않기 때문에 독자가 무슨 의미로 해석해야하는지 명확하지 않다는 것입니다. size=${#1}확실히 유효합니다.
찰스 더피

글쎄, 그건 예기치 않은 일이다. 이 경우 # 1이 $ 1을 대신한다는 것을 몰랐습니다.
Dick Guertin

16
그렇지 않습니다. #일 교체되지 않은 $- $외부는 괄호 여전히 확장 연산자입니다. 는 #언제나처럼, 길이 연산자입니다.
Charles Duffy

유용한 답변이지만 규칙에 대한 예외는 아니기 때문에이 답변을 수정했습니다. @CharlesDuffy가 지적한대로 규칙을 정확하게 따릅니다
Zane Hooper

16

게시물 시작에 대한 응답으로 :

이것을 명령 행 또는 함수 인수와 함께 사용하려면 ...

코드와 함께 :

size=${#1}

길이가 0 인 인수를 확인하고 변수를 저장할 필요가없는 경우가있을 수 있습니다. 이런 종류의 구문을 사용할 수 있다고 생각합니다.

if [ -z "$1" ]; then
    #zero length argument 
else
    #non-zero length
fi

Bash 조건식의 전체 목록은 GNUwooledge 를 참조하십시오 .


11

제공된 예제를 사용하여

#KISS (Keep it simple stupid)
size=${#myvar}
echo $size

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.