Bash의 printf를 사용하여 유니코드 문자열 채우기

Bash의 printf를 사용하여 유니코드 문자열 채우기

나는 bash의 printf로 유니코드 문자열을 채우려고 시도했고 이것을 보았습니다.

printf "%2s" a

예상되는 "a"를 생성합니다.

유니코드 변형

printf "%2s" ä  

놀랍도록 채워지지 않은 "ä"를 생성합니다. (zsh는 예상된 결과를 제공합니다.)

이 문제의 원인은 무엇입니까? bash에서 유니코드 문자열을 어떻게 채우나요?

답변1

문자는 ä2바이트를 사용하여 UTF-8로 인코딩되므로 Printf는 이를 2 패딩으로 처리합니다.

-mWc는 문자열의 문자( )와 바이트( )를 계산할 수 있습니다 . -c그러면 Printf에 주어진 숫자는 입니다 [intended pad]+[bytes]-[chars]. 그래서 저는 이 pad.sh스크립트를 조립했습니다.

#!/bin/sh
bytes=$(printf '%s' "$2" | wc -c)
chars=$(printf '%s' "$2" | wc -m)
n=$(($1+bytes-chars))
printf "%${n}s" "$2"

아래 예제 실행에서는 명확성을 위해 각 출력 뒤에 인위적으로 개행 문자를 추가했습니다.

$ sh pad.sh 10 abcdef
    abcdef
$ sh pad.sh 10 äéßôçÈ
    äéßôçÈ

답변2

Bash에서 유니코드 문자열을 어떻게 채우나요?

이는 bash의 기능을 훨씬 뛰어넘는 것입니다. "유니코드 문자열"을 ascii++로 제한하는 경우(2바이트 문자 없음, bidi 없음, 공백이 아닌 마커 없음 등) 일시적으로 다음과 같이 구성할 수 있습니다.

% pad(){ printf '%*s%s\n' "$(($1-${#2}))" "" "$2"; }
% pad 2 €

답변3

bash는 올바르게 작동하고 C 프로그램은

#include <stdio.h>
main()
{
        char foo[] = "ä";

        printf("%2s\n", foo);
}

행동은 동일합니다.

이는 %s가 바이트 지향 문자열을 참조하고 UTF-8의 "ä"가 2바이트가 되기 때문입니다.

내가 테스트한 한 다른 쉘은 잘못 작동하지 않았습니다.

원하는 결과는 다음을 통해 확인할 수 있습니다.

printf '%2S\n' ä

그러나 제가 테스트한 쉘 중 어느 것도 이를 지원하지 않습니다.

관련 정보