일부 기호는 두 문자 단위를 차지합니다. 다음 스크립트를 고려해보세요.
#!/usr/bin/env bash
echo '银^Htest'
echo 'а^Htest'
산출:
test
test
전자 기호의 코드 포인트를 어떻게 알 수 있나요? 일종의 정규식인가요? 문자열이 차지하는 문자 단위 수를 계산하는 방법은 무엇입니까? 출력에서 모든 것을 어떻게 제거할 수 있나요?
그게 중요하다면 나는 xterm
.
UPD더 큰 그림을 보여드리기 위해 진행 상황을 보여주고, 일부 정보를 출력하고, 지우고, 다시 출력하려고 합니다. 이를 위해 커서를 줄의 시작 부분( \r
)으로 이동하고 공백이 있는 줄을 삭제합니다( tput cols
) 그런 다음 커서를 다시 이동합니다( \r
). 그러나 이 출력은 여러 줄에 걸쳐 있을 수 있다는 것이 밝혀졌습니다. 그래서 문자 수를 세고 뒤로 이동( ^H
)하고 지우고(문자열의 길이만큼 공백을 출력) 다시 뒤로 이동( )하기 로 했습니다 ^H
.
답변1
이것은 실제로 네 가지 질문입니다.
- 코드 포인트를 어떻게 알 수 있나요?
- 일종의 정규식인가요?
- 문자열이 차지하는 문자 단위 수를 계산하는 방법은 무엇입니까?
- 출력에서 모든 것을 어떻게 제거할 수 있나요?
OP에서는 xterm을 언급했지만 마지막 두 개만 xterm에만 해당될 수 있습니다.
(1)과 (2)의 경우 echo 명령은 별로 도움이 되지 않습니다. 사용하시면 좋을 것 같아요printf
, 백슬래시 이스케이프를 인식합니다. 일부 구현에서는(예:GNU 핵심 도구)(유니코드 상수 포함)
printf '\u94f6\btest'
비록일반적인 표현, Perl(UTF-8을 처리할 수 있음)과 같은 스크립팅 언어를 사용하는 것이 더 좋습니다.
추가 자료:
- Bash에서 4자리 유니코드 문자를 어떻게 에코하나요?
- printf 명령
- POSIX 쉘 스크립트에 유니코드 문자를 포함시키는 가장 좋은 방법은 무엇입니까?
- UTF 문자열 변환을 위한 Python의 문자열 리터럴에 해당하는 Bash
질문 (3)과 (4)가 더 흥미롭습니다. 첫째, 스크립트는 문자열에 필요한 문자 단위 수를 미리 알 수 없으며 사실 이후에만 측정할 수 있습니다. 이는 너비가 터미널과 커널 동작의 조합을 기반으로 하기 때문입니다.
- xterm 사용너비문자의 너비를 결정하려면 "와이드"(이중 너비) 글꼴에 몇 가지 문제가 있으며 wcwidth 구현은 모호한 너비 유니코드 값에 대한 개발자 편견을 반영합니다. Markus Kuhn의 복사본을 사용하도록 xterm을 (런타임에) 구성할 수 있습니다.구현하다
wcwidth
;실제 시스템 로케일 정보가 완전하지도 않고 일치하지 않을 수도 있습니다. - xterm이 2바이트 문자의 일부를 지우라고 지시하면(주어진 예에서와 같이) 다른 부분을 공백으로 대체합니다. xterm을 모방하는 대부분의 다른 터미널은 이 작업을 수행합니다(빠른 검사를 통해 한 터미널이 단순히 커서를 움직여 넓은 문자와 ASCII 텍스트가 겹치는 것을 발견했습니다). 만약 너라면알다값은 두 배 너비이며 커서가 있는 위치의 개념을 간단히 조정할 수 있습니다.
- 그 이후의 Linux 커널과
wcwidth
Linux 기반 시스템2004년stty
다음 과 같은 기능이 있습니다iutf8
.
표준 입력 모드에서 올바른 편집 지원을 제공하기 위해 입력이 UTF-8로 인코딩되었음을 커널에 알려줍니다.
- 편집에 유용한 Linux 커널 기능입력하다, 백스페이스 키가 이전 문자를 삭제할 때 터미널 드라이버가 합리적인 작업을 수행하는 데 도움이 되기 때문입니다. 하지만 비교할 만한 기능이 없습니다.산출.
너할 수 있는, 권장되는 대로 커서 위치 보고(이스케이프 시퀀스)를 사용하여 다양한 지점에서 커서 위치를 찾습니다. 하지만 이를 사용하여 선을 지우는 방법을 결정한다면 더 간단해 보입니다.이동하다유니코드 값을 인쇄하기 전의 위치로 이동하여 해당 지점부터 삭제합니다.
또는 와이드 문자를 인쇄하기 전에 커서 위치를 저장한 다음 복원(뒤로 이동)하도록 터미널에 지시할 수 있습니다. 이는 더 깨끗하고 예측 가능해 보일 수 있습니다. 커서 위치가 복원되면 해당 줄을 지울 수 있습니다. 이 세 가지 모두 이스케이프 시퀀스를 사용하여 수행할 수 있습니다.tput
:
tput sc
printf '\u94f6'
tput rc
tput el
printf 'test'
데모인 것 외에도 터미널에 저장된 커서 위치가 하나만 있고 단일/이중 너비 문자가 지워지도록 전체 줄이 지워진다는 단점이 있습니다. 그러나 커서는 결국 "올바른" 위치에 도달하게 됩니다.
- 문자열의 표시 너비를 가져옵니다.
- terminfo - 터미널 기능 데이터베이스(
sc
,el
및rc
)