Bash에서 다른 코드 포인트로 ASCII 문자를 어떻게 인쇄합니까?


12

ASCII 테이블에는 다른 숫자 시스템에 코드 포인트가있는 'J'문자가 있습니다.

Oct   Dec   Hex   Char
112   74    4A    J

그것은 인쇄하여 진수 코드 포인트로이 문자를 인쇄하는 것이 가능 printf '\112'echo $'\112'. 10 진수 및 16 진수 코드 포인트 표시로 동일한 문자를 어떻게 인쇄합니까?


답변:


12

마녀:

printf '\x4a'

12 월 :

printf "\\$(printf %o 74)"

16 진수에 대한 대안 :-)

xxd -r <<<'0 4a'

고맙게도 이것도 작동합니다 awk.
스리 Sarnobat


6

일반적으로 쉘은 다음과 같이 정의 된 경우 변수의 16 진, 8 진 및 10 진수를 이해할 수 있습니다 integers.

$ declare -i v1 v2 v3 v4 v5 v6 v7
$ v1=0112
$ v2=74
$ v3=0x4a
$ v4=8#112
$ v5=10#74
$ v6=16#4a
$ v7=18#gg
echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304

또는 "산술 확장"의 결과입니다.

$ : $(( v1=0112, v2=74, v3=0x4a, v4=8#112, v5=10#74, v6=16#4a, v7=18#gg ))
$ echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304

따라서 변수 값에 속하는 문자를 인쇄하는 한 가지 방법 만 있으면됩니다.
그러나 두 가지 가능한 방법이 있습니다.

$ var=$((0x65))
$ printf '%b\n' "\\$(printf '0%o' "$var")"
e

$ declare -i var
$ var=0x65; printf '%b\n' "\U$(printf '%08x' "$var")"
e

두 개의 printf가 필요합니다. 하나는 값을 16 진수 문자열로 변환하고 다른 하나는 실제로 문자를 인쇄합니다.

두 번째는 모든 유니 코드 포인트를 인쇄합니다 (콘솔이 올바르게 설정된 경우).
예를 들면 다음과 같습니다.

$ var=0x2603; printf '%b\n' "\U$(printf '%08x' "$var")"

눈 사람.

utf-8 표현이있는 문자 f0 9f 90 ae0x1F42E입니다. 검색 cow face site:fileformat.info하는 그것을 얻을 :

$ var=0x1F42F; printf '%b\n' "\U$(printf '%08x' "$var")"
🐮

참고 : 4.3 이전 버전의 bash (버전에서 수정 됨)의 유니 코드 방식에는 128 및 255 사이의 문자 (10 진수)가 잘못 인쇄 될 수있는 문제가 있습니다.


참고 문헌

넷째 단락 내부 PARAMETERS에서 man bash:

변수에 정수 속성이 설정되어 있으면 $ ((...)) 확장을 사용하지 않아도 값은 산술 연산 식으로 평가됩니다 (아래의 산술 확장 참조).

"ARITHMETIC EVALUATION"내부 man bash:

앞에 0이있는 상수는 8 진수로 해석됩니다. 선행 0x 또는 0X는 16 진수를 나타냅니다. 그렇지 않은 경우 숫자는 [base #] n 형식을 취합니다. 여기서 선택적 기준은 산술 기준을 나타내는 2에서 64 사이의 10 진수이며 n은 해당 기준의 숫자입니다. base #가 생략되면 base 10이 사용됩니다. 9보다 큰 숫자는 소문자, 대문자 @ 및 _ 순서로 표시됩니다. 밑이 36보다 작거나 같은 경우 소문자와 대문자를 서로 바꿔서 사용하여 10에서 35 사이의 숫자를 나타낼 수 있습니다.


@ StéphaneChazelas 음, 코드 포인트는 (항상) 바이트 값이 아닙니다. Bash (4.3 이전 버전)는 코드 포인트의 바이트 값을 제공합니다. 즉 é, 항상 printf '\351'바이트 값을 인쇄하므로 문자 (Octal : 351, Dec : 233, Hex : 0xE9)가 잘못 인쇄됩니다 0xE9. ISO-8859-1작동 할 수 있는 인코딩 (및 사촌)을 가진 터미널의 경우 utf-8 인코딩 터미널에서는 바이트 값이 0xE9 로 나타납니다. 계속 ....
아이작

@ StéphaneChazelas 예를 들어 "bash 4.2 잘못 인코딩 됨"을 처음으로 발견 하고 검색 한 것은 아닙니다 . bash 4.3 이상에서 수정되었습니다.
Isaac Isaac

확인. 나는 당신이 지금 무슨 뜻인지 알았습니다 (이전 버전의 답변에 따라 4.3으로 테스트하고있었습니다). bash-4.2 뿐이며 bash-4.1은 지원하지 않습니다 \u(zsh에서 제공).
Stéphane Chazelas


0

POSIX Awk stdlib 라이브러리를 사용할 수 있습니다 .

$ awklib 'BEGIN {print str_chr(74)}'
J

$ awklib 'BEGIN {print str_chr(+base_conv("4A", 16, 10))}'
J

$ awklib 'BEGIN {print str_chr(+base_conv(112, 8, 10))}'
J

$ awklib 'BEGIN {print str_chr(+base_conv(1001010, 2, 10))}'
J

0

변환 할 숫자 목록이 있고 함수 호출을 피하고 각 문자에 대한 서브 쉘을 작성하려는 경우 사전에 ASCII 세트를 정의 할 수 있습니다.

ascii=$(for x in {0..9} {A..F}; do for y in {0..9} {A..F}; do echo -ne "\x$x$y"; done; done)

널 문자는 제외되므로 모든 문자는 1 씩 오프셋됩니다.

그런 다음 다음과 같이 사용하십시오 (한 줄에 1 숫자로 가정).

while read c; do out+="${ascii:$c-1:1}"; done <<< "$in"
echo "$out"

0

다음은 다음을 사용하는 모든 변환입니다 printf.

printf "%o" "'J" # 112 (oct)
printf "%d" "'J" # 74 (dec)
printf "%x" "'J" # 4a (hex)

printf '\112' # J (oct)
printf "\x$(printf %x 74)" # J (dec, requires double conversion)
printf '\x4a' # J (hex)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.