printf를 사용하여 인수로 전달된 유니코드 문자를 디코딩해 보세요.

printf를 사용하여 인수로 전달된 유니코드 문자를 디코딩해 보세요.

파이프로 연결한 유니코드 코드를 인쇄하려고 합니다.

echo 0024 0025 | xargs -n1 echo # one code per line
  | xargs printf '\u%s\n'

이것을 얻을 수 있기를 바랍니다

$
%

하지만 그게 내가 얻은 거야

printf: missing hexadecimal number in escape

몇 번의 시행착오 끝에 저는 실제로 두 가지 작은 질문을 갖게 되었습니다. 하나는 이해가 되는 질문이고 다른 하나는 완전히 미스터리인 것 같습니다.


질문 1:

printf '\u%s\n' 0024 0025

나에게 이것을 줘

-bash: printf: missing unicode digit for \u
\u0024
-bash: printf: missing unicode digit for \u
\u0025

질문 2:

> # use built-in for $
> printf '\u0024\n'
$
> # use exe for $
> which printf
/usr/bin/printf
> /usr/bin/printf '\u0024\n'
$
> # now use built-in for %
> printf '\u0025\n'
%
> # but look what happens when we use exe for % !!!!
> /usr/bin/printf '\u0025\n'
/usr/bin/printf: invalid universal character name \u0025

( >for 를 사용하면 출력에서 ​​볼 수 있습니다 $)$

어떤 이유로 일부 문자는 exe 버전에서 작동하지만 일부 문자는 그렇지 않습니다. 단, 모든 문자는 내장 printf에서 작동합니다.


따라서 문제 #2가 아닌 경우에 작동할 수 있는 해결 방법은 다음과 같습니다(그러나 원래 아이디어보다 훨씬 느릴 수 있음).

echo 0024 0025 | xargs -n1 echo # one item per line
  | xargs -I {} printf '\u{}\n'

그러나 문제 #2로 인해 작업의 절반만 수행됩니다.

$ echo 0024 0025 | xargs -n1 echo | xargs -I {} printf '\u{}\n'
$
printf: invalid universal character name \u0025

($는 나오지만 %는 오류를 냅니다)


그래서 내 질문은 다음과 같습니다.

- 각 인수에 대해 한 번이 아니라 한 번만 printf를 실행할 수 있도록 printf에서 숫자 코드를 사용하도록 하는 방법이 있습니까 -I?

printf-내장 기능은 신경 쓰지 않지만 printfexe는 마음에 들지 않지만 에 대해서만 마음에 들지 %않고 에 대해서는 마음에 들지 않는다는 점에서 내가 뭘 잘못하고 있습니까 $?

답변1

이중 확장 문제( \u이전에 처리된 )를 방지하려면 최소한 Bash에서 를 %s사용할 수 있습니다 .%bprintf

printf '%b\n' \\u0024 \\u0025

다양한 방법으로 입력을 전처리할 수 있습니다.

set 0024 0025
printf '%b\n' "${@/#/\\u}"

떨어져 있는 printf,GNU coreutils에서 구현됨, 유니코드 문자 사양에는 다음과 같은 제한 사항이 있습니다.

printfISO C 99에 도입된 두 가지 문자 구문을 설명하십시오. ' \u'는 4개의 16진수 숫자로 지정된 16비트 유니코드(ISO/IEC 10646) 문자를 나타냅니다.헤헤, ' \U'는 8자리 16진수로 지정된 32비트 유니코드 문자를 나타냅니다.하하하하. 유니코드 문자는 로케일 설정 printf에 따라 출력됩니다. LC_CTYPE이 구문은 U+0024($), U+0040(@) 및 U+0060(`)을 제외하고 U+0000…U+009F, U+D800…U+DFFF 범위의 유니코드 문자를 지정할 수 없습니다.

이것이 왜 이런 방식으로 생산할 수 없는지 설명합니다 %.

답변2

이스케이프 시퀀스는 표준 printf유틸리티 에서 지원되지 않습니다 \uxxxx. 다음을 참조하세요.https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html

이 작업이 일부 구현(예: 내장 ksh)에 존재할 수 있는 확장에 따라 달라지지만 보편적인 지원은 기대할 수 없다고 가정합니다. 표준 문서를 참조하세요 printf.

또 다른 문제는 당신이 전화한다고 가정하는 것 같습니다

printf '\u%s\n' 123

다음을 호출하는 것과 동일한 결과가 생성됩니다.

printf '\u123\n'

printf형식 문자열은 요소별로 구문 분석되기 때문에 작동하지 않지만 예상되는 형식 문자열은 표시되지 않습니다.

bash따라서 이를 사용하여 스크립트를 실행하는 경우에도 \uxx백슬래시 이스케이프 뒤에 두 개의 16진수 숫자가 있고 이스케이프 시퀀스가 ​​형식 문자열에 문자 그대로 나타나면 백슬래시 이스케이프가 확장될 것으로 예상할 수 있습니다. 4개의 16진수를 확장하려면 \Uxxxx형식 문자열에서 문자 그대로 확장해야 합니다.

관련 정보