터미널 출력에 단위 구분 기호(ASCII 31)가 표시되지 않는 이유는 무엇입니까?

터미널 출력에 단위 구분 기호(ASCII 31)가 표시되지 않는 이유는 무엇입니까?

단위 구분 기호 ASCII 문자(ASCII 31, 8진수 37)는 Vim에서 ^_. 하지만 동일한 파일을 터미널에 인쇄하면 문자가 보이지 않습니다. 이로 인해 한 줄의 필드가 서로 붙어 있습니다.

# In Vim and less:

first field^_second field^_last field

# cat the same file to terminal:
cat delim.txt
first fieldsecond fieldlast field

# print 2nd field with awk 
cat delim.txt | awk 'BEGIN {FS = "\037"} {print $2}'
second field

cat -v를 사용하면 단위 구분 기호를 표시할 수 있다고 가정합니다.

cat -v delim.txt
first field^_second field^_last field

그런데 이게 오히려 번거롭습니다. Bash 셸에서 stdout으로 인쇄할 때 단위 구분 기호가 눈에 보이지 않는 이유는 무엇입니까? 쉘 출력을 올바르게 복사하여 붙여 넣을 수도 없습니다. 이 과정에서 단위 구분 기호가 손실됩니다.

답변1

US라고도 하는 단위 구분 기호( ) 문자는 문자 클래스 IS1에 속하며 다음과 같습니다.cntrl~ 아니다print캐릭터 클래스 에서 텍스트를 그룹으로 정리하기 위한 제어 문자입니다.해당 정보를 활용하도록 설계된 프로그램의 경우. 일반적으로 인쇄할 수 없는 문자는 다양한 프로그램이나 환경에서 다르게 해석되고 렌더링될 수 있습니다.

Vim에서처럼 나타나는 이유는 ^_Vim이 대화형 편집기이기 때문입니다. 올바른 이진 문자가 디스크에 기록되는 한 인쇄할 수 없는 문자를 원하는 대로 자유롭게 렌더링할 수 있습니다.

Unix 쉘 프로그램은 일반 텍스트를 작동하고 서로 전달하도록 작성되었기 때문에 쉘에서는 동일한 동작을 얻을 수 없습니다. 파일을 작성할 때 cat터미널에 기록되는 텍스트는 실제로 파일에 있는 내용이어야 합니다.

따라서 문자를 해석하는 것은 터미널 장치에 맡깁니다. 그리고 일부 터미널 에뮬레이터는하다US다른 캐릭터와 다르게 캐릭터를 렌더링합니다 . gnome-terminal(또는 모든 기반 터미널) 에서 vte문자는 16진수 코드를 포함하는 상자로 렌더링됩니다 001F. xterm또는 에서는 rxvt캐릭터가 실제로 보이지 않습니다.

답변2

단위 구분 기호는 ASCII 범위에 있습니다.제어 문자, 따라서 시각적 표현이 없거나 일반적으로 있어서는 안 됩니다.

Vim과 일부 다른 편집자는 이를 표시하므로 편집할 수 있습니다. 아시다시피, cat -v그것도 표시합니다. 매뉴얼 페이지에는 인쇄할 수 없는 문자를 인쇄 가능한 표현으로 바꾸는 의 -v짧은 형식이 표시됩니다. 이는 파일의 원래 내용이 아니므로 출력이 실제로 다른 프로그램에 대한 경우 문제를 일으킬 수 있습니다. --show-nonprinting.

여러분이 보는 표현은 이미 제어 문자임을 암시합니다. 앞에 a가 붙은 문자는 터미널에서 이 문자를 생성하는 키 조합인 + 문자에 ^대한 일반적인 표기법입니다 . 예를 들어 +를 사용하면 vim에 단위 구분 기호를 입력할 수 있습니다. 그러나 다른 편집기나 일부 GUI 뷰어는 16진수 코드, 자리 표시자 또는 완전히 다른 것을 표시할 수 있습니다.CtrlCtrl_

터미널은 제어 문자를 인쇄하지 않으므로 텍스트를 선택할 때도 복사되지 않습니다(여기에서는 제어 문자인 개행 및 탭과 같은 공백 문자도 예외입니다). 복사할 때 일반적으로 무시되는 터미널 제어 문자의 또 다른 예는 ESC문자 뒤에 텍스트 색상을 지정하기 위한 코드가 오는 색상 코드입니다.

따라서 터미널에 문자를 표시하려면 단위 구분 기호를 인쇄 가능한 문자로 바꾸는 프로그램을 사용하는 것 외에는 다른 방법이 없습니다.

답변3

변경하려는 경우 다른 (매우 좋은) 답변의 여백에 약간오직파일 내용을 표시할 때 제어 문자를 사용 ^_하고 싶을 수도 있습니다.바꾸어 쓰다tr유틸리티(및 약간의 bash 호환 구문)를 사용하여 다음을 수행합니다 .

# Replace the control character US (^_) by *one* other character
$ cat my.file | tr $'\c_' ':'

해당 제어 문자를 "확장된" 형식으로 바꿔야 하는 경우 sed대신 다음이 필요합니다.

# Replace the control character US (^_) by any string
cat /tmp/f | sed s/$'\c_'/^_/g

구문에 유의하세요 $'\cX'. 이 구문은 (bash 호환 셸)에 해당 제어 문자를 바꾸도록 알려줍니다. 보다제어 문자 별칭 목록은 Wikipedia"캐럿 표기법"을 사용합니다. 해당 구문이 마음에 들지 않으면 대신 8진수 $'\037'또는 16진수 $'\x1f'표기법을 사용하는 것이 좋습니다.

관련 정보