단자 분리기에서 단위 분리기 (ASCII 31)가 보이지 않는 이유는 무엇입니까?


17

단위 구분 기호 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으로 인쇄 할 때 단위 분리기가 왜 시각적으로 표시되지 않습니까? 쉘 출력을 올바르게 복사하여 붙여 넣을 수도 없습니다. 프로세스에서 단위 분리기가 손실됩니다.


모든 문자를 인쇄 할 수있는 것은 아니며 단위 구분 기호 중 하나입니다. 일부 편집자는 편집 할 수 있도록 어떤 방식 으로든 표시합니다. 모호성을 줄이기 위해 인쇄 가능한 문자 시퀀스 및 다른 글꼴 / 컬러로 변환해야합니다.
ctrl-alt-delor

3
31 및 127 미만의 ASCII 코드는 터미널 또는 장치가 무언가를 수행 (따라서 제어 코드라고하는 이유) 시키거나 무언가를 표시하는 대신 프로토콜 (EOT 또는 SOH와 같은)에서 무언가를 나타내도록 고안되었습니다. 터미널이 타자기와 같은 장치 였을 때 다시 들었고 텔레타이프에 캐리지 리턴을 지시하는 것과 같은 것이 실제로 필요했습니다. 편집자는 무언가를 편집하고 실제로 제어 코드가 요구하는 것을 수행하기 위해 터미널을 사용하고 싶지 않기 때문에 "^"표기법을 사용하여 렌더링하도록 선택할 수 있습니다.
LawrenceC

1
@LawrenceC : 코드 127은 실제로 터미널이 아무 것도 하지 않도록 의도했습니다 . 테이프를 펀칭하고 실수를 한 경우, 버튼을 누르면 테이프를 한 칸씩 백업하고 "rub-out"을 눌러 모든 것을 펀치 할 수 있습니다 여덟 구멍. 독자가 모든 구멍을 뚫은 캐릭터를 만나면 와이어를 통해 보내지 만 수신자는 무시할 수 있습니다.
supercat 2016 년

답변:


19

단위 세퍼레이터 ( US라고도) 문자는 IS1상기에 cntrl문자 클래스이고 하지print문자 클래스. 텍스트를 그룹으로 구성하고 해당 정보를 사용하도록 설계된 프로그램 의 제어 문자입니다 . 일반적으로 인쇄 할 수없는 문자는 다른 프로그램이나 환경에서 다르게 해석되고 렌더링 될 수 있습니다.

^_Vim에서 와 같이 표시되는 이유 는 Vim이 대화식 편집기이기 때문입니다. 올바른 이진 문자가 디스크에 기록되는 한 인쇄 할 수없는 문자를 자유롭게 렌더링 할 수 있습니다.

Unix 쉘 프로그램이 서로 작동하고 일반 텍스트를 전달하도록 작성되었으므로 쉘에서 동일한 동작을 얻을 수 없습니다. 때 cat파일, 파일에 실제로 무엇을해야 단말기에 기록 된 텍스트입니다.

문자를 해석하기 위해 터미널 장치에 남겨 둡니다. 그리고 일부 터미널 에뮬레이터 US 문자를 다른 문자와 다르게 렌더링합니다 . 에서 gnome-terminal(또는 임의의 vte기반 단말기), 문자가 16 진수 코드를 포함하는 상자로 렌더링한다 001F. 에서 xterm또는 rxvt, 문자는 참으로 보이지 않습니다.


그럼 내가 언급하지 않았다는 US것입니다 완전히 보이지 않는. Ctrl+/(을 통해 확인 <C-v><C-/>) 을 사용하여 해당 문자를 터미널에 삽입 하면 예상치 못한 양의 텍스트가 줄에서 삭제됩니다. 나는 그 동작을 완전히 이해하지 못하지만 주로 공백을 삽입하는 대신 여러 문자를 삭제하지만 때로는 무작위로 텍스트를 삽입하는 일종의 "역 탭"효과가있는 것 같습니다. .
Braden Best

10

단위 구분 기호는 ASCII 범위의 제어 문자 이므로 시각적으로 표시되지 않아야합니다 (또는 일반적으로 표시해서는 안 됨).

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

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

터미널은 제어 문자를 인쇄하지 않으므로 텍스트를 선택할 때도 복사되지 않습니다 (여기서 줄 바꿈 및 탭과 같은 공백 문자는 제어 문자이기도 함). 터미널에서 복사 할 때 일반적으로 무시되는 제어 문자의 또 다른 예는 색상 코드이며, ESC문자 다음에 텍스트를 색칠하기위한 코드가 있습니다.

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


3

다른 (매우 좋은) 대답의 여백에 약간의 영향을 미칩니다. 파일 내용을 표시 할 때 제어 문자 변경 하려면 유틸리티 (및 약간의 bash 호환 구문)를 사용하여 음역을^_ 원할 수 있습니다 :tr

# 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'표기법을 대신 사용하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.