문자

문자

나는 다음을 사용하여 변환합니다.정수도착하다성격그리고성격도착하다정수배쉬에서. 그러나 나는 printf \\$(printf '%03o' $1)어떻게 일하는지 이해하지 못합니다 printf '%d' "'$1". 어떻게 printf \\$(printf '%03o' $1)작동하는지 설명해주세요 printf '%d'.

#!/bin/bash
# chr() - converts decimal value to its ASCII character representation
# ord() - converts ASCII character to its decimal value

chr() {
  printf \\$(printf '%03o' $1)
}

ord() {
  printf '%d' "'$1"
}

ord A
echo
chr 65
echo

답변1

printf '\101'여기서 1018진수는 해당 값으로 바이트를 출력합니다.

AASCII 터미널로 전송되면 ASCII A및 모든 ASCII 호환 문자 세트(대부분의 최신 문자 세트가 포함되지만 일부 IBM 시스템에서는 여전히 사용되는 EBCDIC 문자 세트가 포함됨) 의 문자 65(8진수 101) 로 렌더링됩니다 .

존재하다

printf \\$(printf '%03o' $1)

다음과 같이 작성되어야 합니다:

printf "\\$(printf '%03o' "$1")"

Bourne과 같은 쉘에서는 매개변수 확장(예: $1) 또는 명령 대체( $(...))를 따옴표로 묶지 않은 채로 두는 것이 분할+글로브 연산자이므로 여기서는 필요하지 않습니다.

  • printf '%03o' "$1"$1숫자를 3자리 8진수로 변환
  • printf "\\$(...)"\해당 8진수를 a ( \\큰따옴표 안에 있음 ) 에 추가하고 \전달하여 printf해당 바이트 값을 출력합니다.

문자 세트가 문자당 1바이트인 로케일(예: iso8859-1) 또는 멀티바이트 문자 세트가 있는 로케일에서만 작동하며 값은 0~127에 대해서만 작동합니다.

존재하다 bash,

printf '%d\n' "'A"

문자의 유니코드 코드 포인트를 인쇄합니다 A(또는 최소한 GNU 시스템에서는 반환된 값이 mbtowc()최소한 유니코드 코드 포인트입니다).

일부 다른 구현(독립형 GNU printf유틸리티 포함)은 문자의 첫 번째 바이트 값을 반환합니다.

이는 ASCII 기반 시스템과 같은 ASCII 문자에는 A아무런 차이가 없지만 다른 문자의 경우에는 중요합니다. 예를 들어 그리스 α문자(U+03B1)는 다음과 같이 인코딩됩니다.

  • iso8859-7의 바이트 225(표준 그리스어 단일 바이트 문자 집합)
  • UTF-8의 바이트 206 177(Unix 계열 시스템에서 가장 일반적으로 사용되는 유니코드 인코딩)
  • GB18030(유니코드의 공식 중국어 인코딩)의 바이트 166193입니다.

Bash는 로케일에 관계없이(적어도 GNU 시스템에서는) 유니코드 코드 포인트인 (16진수로 0x03b1)을 printf '%d\n' "'α"항상 출력 하지만 다른 언어는 로케일에 따라 225, 206 또는 166을 반환할 수 있습니다.945α

ASCII 문자(또는 값 0~127) 또는 모든 문자의 문자 집합(값 0~255)을 사용하는 로케일의 경우 이러한 chr합계는 ord단순히 서로 역수임을 알 수 있습니다.iso8859-1

유니코드 코드 포인트를 반환하려는 경우 ord()그 반대(유니코드 코드 포인트에 해당하는 문자 인쇄)는 다음과 같습니다.

chr() {
  printf "\U$(printf %08X "$1")"
}

bash( 4.3 이상 가정 ( \UXXXXXXXX4.2에 추가되었지만 4.3 이전에는 U+0080 ~ U+00FF 문자에 대해 제대로 작동하지 않았습니다)).

그런 다음 모든 로캘에서 다음을 수행합니다.

$ ord α
945
$ chr 945
α

또는 ord()(현재 로케일에서) 주어진 문자의 인코딩된 바이트 값을 반환합니다:

ord() {
  printf %s "$1" | od -An -vtu1
}

다음 바이트를 출력 합니다 chr().

chr() {
  printf "$(printf '\\%o' "$@")"
}

그런 다음 예를 들어 UTF-8 로케일에서 다음을 수행합니다.

$ ord α
 206 177
$ chr 206 177
α

(당신은 ord α945를 받게 될 것이고, chr그리고 의 쓰레기를 받게 될 것입니다 chr 945) chr 206 177.

또는 로케일에서 사용하십시오 iso8859-7.

$ ord α
 225
$ chr 225
α

(945를 제공하지만 GNU 시스템에서 if로 바꾸면 ord α225가 제공될 수 있습니다.)printf/usr/bin/printf

답변2

내부적으로 8진수 값(예: 65)(65 -> 101)을 printf '%03o' $1반환합니다 .$1

printf \\$(..)8진수 값으로 표시되는 문자를 외부적으로 인쇄합니다.

라인 참조 man printf:

\NNN 8진수 값 NNN 바이트(1~3자리)

단일 문자 상수로 처리되어야 함 을 나타내도록 printf '%d' "'$1"지정해야 하기 때문에 그렇지 않으면 printf에서 값이 잘못된 숫자임을 나타내는 오류가 발생합니다. 그런 다음 문자 상수 값을 사용하여 10진수 형식으로 인쇄합니다.'$1printf"%d"

답변3

문자

printf \\$(printf '%03o' $1) # 다음과 같아야 합니다...printf "$(printf '\\%03o' "$1")"

첫 번째는 printf두 번째 출력을 사용하여 문자를 생성합니다. 우리는 그것을 해독하기 위해 거꾸로 작업해야 합니다.

두 번째는 printf정수( $1)를 8진 정수( '%03o'형식)로 변환하는 데 사용됩니다.

$ printf '%03o' 12
014
$ printf '%03o' 65
101
$ printf '%03o' 255
377

그런 다음 결과는 an \(셸에 대한 특별한 의미를 피하기 위해 두 배로 묶거나 따옴표로 묶어야 함)에 해당하는 항목과 연결됩니다. 결과 문자열은 \101바이트의 8진수 값으로 해석됩니다. 하지만 단지최대 3자리(대부분의 printf 쉘 구현에서) 이 유형의 형식은 단일 바이트 0-255(또는 8진수로 0-377)에 사용되기 때문에 3개의 8진수만 해석됩니다. 따라서 대부분의 printf 구현은 8진수만 다음으로 변환합니다.바이트. 바이트가 콘솔에서 사용하는 로캘의 ASCII 문자를 나타내는 경우 해당 문자가 인쇄됩니다.

$ printf \\101\\n
A
$ printf \\377\\n

로케일의 영향을 받는 문자(바이트 대신)를 인쇄하려면 다음이 필요합니다.

  • printf를 생성할 수 있음멀티바이트사용되는 로케일의 문자
  • 바이트 대신 문자를 원하는 표현 형식

예를 들어 bash(4.3+)에서는 다음과 같습니다.

$ printf \\U263A\\n

많은 printf숫자를 인쇄할 수 있습니다.

$ printf '%03o\n' 1495195076287004671
122777777777777777777

그러나 처음 3개만 8진수로 허용됩니다.

$ printf '\122777777777777777777'
R777777777777777777                     # Note the R in the front.

주문하다

printf '%d' "'$1"

데이터(비형식) 문자열은 외부 따옴표를 제거하고 결과 문자열은 로 시작합니다 . 'a 또는 a로 '시작하는 문자열은 "printf에 특별합니다. 이러한 문자열의 경우 형식은 다음과 같습니다.숫자, 이것~의첫 번째 문자인쇄(숫자 형식 문자열로 지정된 형식):

$ printf '%d\n' '"A'      # decimal (doesn't expand quoted vars '"$var')
65
$ printf '%d\n' "'A"      # decimal
65
$ printf '%o\n' "'A"      # octal
101
$ printf '%x\n' "'A"      # Hexadecimal
41

"'…"해석에 따라 약간의 차이가 있음을 참고하세요.첫 번째 문자구현 사이(바이트 또는 문자, 바이트의 경우 결과는 사용된 로케일의 영향을 받음)

관련 정보