grep을 사용할 때 화면에 이상한 기호가 나타납니까?

grep을 사용할 때 화면에 이상한 기호가 나타납니까?

./trans ... 이스케이프 코드의 명령 출력을 표시합니다.

원인이 무엇인지 아시나요? grep이 없으면 ISO 코드와 공백만 표시됩니다.

사용된 소프트웨어

주문하다:./trans --id --input /path/to/txt | grep ISO | grep [a-z]

root@box /test # alias grep
alias grep='grep --color=auto'
root@box /test # type grep
grep is aliased to `grep --color=auto'

일반 출력:

읽을 수 있는 텍스트와 URL이 포함된 trans 명령 출력

답변1

스크린샷에 손상이 있는 것으로 나타남ANSI 색상 코드, 텍스트 렌더링을 제어합니다. 굵은/밝은 텍스트는 일반적으로 터미널에서 해석되는 시퀀스로 생성되며 ␛[1m화면에 직접 표시되지 않습니다. 단지 텍스트의 다음 비트를 더 밝게 만듭니다. unped 출력의 스크린샷을 grep보면 각 줄의 레이블과 값 사이에 색상 차이가 있어 원본 출력에서는 이를 사용하고 있음을 알 수 있습니다.

grep코드의 "m"(문자이므로 [a-z])과 일치하고 빨간색으로 강조 표시되는 Final 에 의해 시퀀스가 ​​중단된 것 같습니다 . 이로 인해 터미널이 처리할 수 없는 부분 이스케이프 시퀀스가 ​​남습니다.

이스케이프 문자 는 U+001B이며, 이는 알 수 없는 문자 상자에 표시되는 16진수입니다. 표시되는 것은 이스케이프 문자(상자), a [, a 1, 빨간색 m다음에 예상되는 일치 텍스트 "eng"입니다. 마지막 "22"("일반 색상 및 강도"에 대한 숫자 코드)에서도 동일한 일이 발생합니다.


손상된 출력은 실제로 다음과 같습니다.

␛[1␛[31분사나운␛[22분␛[22␛[31분␛[22분 

여기서 ␛[31m텍스트를 빨간색으로 만들고 ␛[22m다시 흰색으로 바꿉니다. 둘 다 문자를 둘러싸서 원본 텍스트에 grep삽입됩니다 . m원본 텍스트는 다음과 같습니다.

 ␛[1분영어␛[22분 

이렇게 하면 " eng"이 밝아지고 다시 일반 텍스트로 전환됩니다.

grepFinal 을 로 변경 grep --color=always하고 input 을 파이핑하여 이를 확인할 수 있습니다 hexdump. 그러면 인쇄할 수 없는 모든 문자와 터미널에서 해석되는 문자가 표시됩니다.


몇 가지 방법으로 이 문제를 처리할 수 있습니다. 하나는 grep당분간 별칭을 사용하지 않는 것입니다.

./trans --id --input /path/to/txt | grep ISO | \grep [a-z]

백슬래시는 일시적으로 별칭을 건너 grep뛰고 직접 실행됩니다.

또 다른 방법은 원래 명령에서 ANSI 코드를 제거하는 것입니다. 이에 대한 몇 가지 제안 사항이 있습니다.이 질문에는:

./trans --id --input /path/to/txt | perl -pe 's/\e\[[\d;]*m//g' | grep ISO | grep [a-z]

또 다른 옵션은 끝에 외부 파이프를 추가하는 것입니다.

./trans --id --input /path/to/txt | grep ISO | grep [a-z] | cat

Final grep의 출력은 TTY로 직접 전달되지 않고 파이프로 연결되므로 cat색상 강조 표시를 삽입하지 않습니다.

아마도 가장 좋은 옵션은 터미널에 연결되지 않은 경우 자체 출력에서 ​​터미널 제어 시퀀스를 사용하는 Translate Shell을 먼저 중지하는 것입니다. 여기에는 작성자에게 제출하는 버그 보고서와 ansi()Translate Shell 기능에 대한 코드 수정이 적절하게 포함되지만 이를 약간 피할 수 있습니다.

TERM=dumb ./trans --id --input /path/to/txt | grep ISO | grep [a-z]

이는 dumb적어도 ECMA-48 색상을 지원하지 않는 것으로 인식되는 Translate Shell 환경의 터미널 유형을 전달합니다. (불행히도 Translate Shell은 terminfo를 사용하지 않으며 단순히 자신이 이해하는 터미널 유형과 사용하는 제어 시퀀스를 자체 코드에 직접 연결합니다.)

관련 정보