
나는 다음을 사용하여 변환합니다.정수도착하다성격그리고성격도착하다정수배쉬에서. 그러나 나는 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'
여기서 101
8진수는 해당 값으로 바이트를 출력합니다.
A
ASCII 터미널로 전송되면 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 이상 가정 ( \UXXXXXXXX
4.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진수 형식으로 인쇄합니다.'
$1
printf
"%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
"'…"
해석에 따라 약간의 차이가 있음을 참고하세요.첫 번째 문자구현 사이(바이트 또는 문자, 바이트의 경우 결과는 사용된 로케일의 영향을 받음)