텍스트 스트림에서 ANSI 색상 코드 제거


73

의 출력 검사

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";'

텍스트 편집기 (예 vi:)에서 다음을 보여줍니다.

^[[37mABC
^[[0m

출력 파일에서 ANSI 색상 코드를 어떻게 제거합니까? 가장 좋은 방법은 스트림 편집기를 통해 출력을 파이프하는 것입니다.

다음은 작동하지 않습니다

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | perl -pe 's/\^\[\[37m//g' | perl -pe 's/\^\[\[0m//g'

질문에 대한 답은 아니지만 출력을 파이프로 보내 more거나 less -R이스케이프 코드를 텍스트 편집기 대신 색상으로 해석 할 수도 있습니다.
terdon

답변:


97

문자 ^[[37m^[[0m의 일부 ANSI 이스케이프 시퀀스 (CSI 코드) . 이 사양 도 참조하십시오 .

GNU 사용 sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b(나 \x1B)이있다 이스케이프 특수 문자
    ( sed대안을 지원하지 않습니다 \e\033)
  • \[ 이스케이프 시퀀스의 두 번째 문자입니다
  • [0-9;]* 색상 값 정규식입니다.
  • m 이스케이프 시퀀스의 마지막 문자입니다

⚠ macOS에서 기본 sed명령은 주석에서 slmsteamer25\e 로 지적 된 것과 같은 특수 문자를 지원하지 않습니다 . 대신 을 사용하여 설치할 수 있습니다 .gsedbrew install gnu-sed

OP의 명령 줄을 사용한 예 :   (OP는 원본 포스터를 의미)

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | 
      sed 's/\x1b\[[0-9;]*m//g'

Tom Hale 은 그래픽 모드 (컬러) 이스케이프 시퀀스에 고유 [a-zA-Z]한 문자 대신 다른 모든 이스케이프 시퀀스를 제거 할 것을 제안 m합니다. 그러나 [a-zA-Z]너무 넓어서 너무 많이 제거 할 수 있습니다. 마이클 Faleński미구엘 모타 사용하여 일부 이스케이프 시퀀스를 제거하기 위해 제안 [mGKH]하고 [mGKF]각각. Britton Kerin 은 오류 / 경고 에서 색상을 제거하는 K것 외에 사용해야 함을 나타냅니다 (리디렉션하는 것을 잊지 마십시오 ).mgccgcc 2>&1 | sed...

sed 's/\x1b\[[0-9;]*m//g'           # Remove color sequences only
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'    # Remove all escape sequences
sed 's/\x1b\[[0-9;]*[mGKH]//g'      # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKF]//g'      # Remove color and move sequences
Last escape
sequence
character   Purpose
---------   -------------------------------
m           Graphics Rendition Mode (including Color)
G           Horizontal cursor move
K           Horizontal deletion
H           New cursor position
F           Move cursor to previous n lines

사용 perl

sed일부 운영 체제 에 설치된 버전은 제한적일 수 있습니다 (예 : macOS). 이 명령 perl은 일반적으로 더 많은 운영 체제에서 설치 / 업데이트하기가 더 쉽다는 장점이 있습니다. Adam KatzPCRE 에서 \e(와 동일 \x1b) 사용할 것을 제안합니다 .

필터링 할 명령 수에 따라 정규식을 선택하십시오.

perl -pe 's/\e\[[0-9;]*m//g'          # Remove colors only
perl -pe 's/\e\[[0-9;]*[mG]//g'
perl -pe 's/\e\[[0-9;]*[mGKH]//g'
perl -pe 's/\e\[[0-9;]*[a-zA-Z]//g'
perl -pe 's/\e\[[0-9;]*m(?:\e\[K)?//g' # Adam Katz's trick

OP의 명령 줄을 사용한 예 :

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' \
      | perl -pe 's/\e\[[0-9;]*m//g'

용법

에 의해 지적 스튜어트 Cardall 의 의견이 sed명령 줄은 프로젝트에서 사용하는 궁극적 인 Nginx에 나쁜 봇 이메일 보고서를 정리 (1000 점) ;-)


2
sed명령과 설명에 감사드립니다 . :)
Redsandro

2
일부 색상 코드 (예 : Linux 터미널)에는 접두사가 포함되어 있습니다. 예를 들어 정규 표현식에 1;31m더 잘 추가 ;하십시오 cat colored.log | sed -r 's/\x1b\[[0-9;]*m//g'. 그렇지 않으면 제거되지 않습니다.
Redsandro

1
이것은 github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/blob/… 에서 이메일 보고서를 정리하는 데 사용됩니다 .
스튜어트 Cardall

2
그러나 OSX 버전은 sed그림과 같이 작동하지 않았지만 버전은 작동 gsed합니다.
slm

2
OSX sed에 대한 slm의 의견에 대한 추가 컨텍스트 : \ x1b와 같은 제어 문자를 지원하지 않습니다. 예 : stackoverflow.com/a/14881851/93345 . 를 통해 gsed 명령을 얻을 수 있습니다 brew install gnu-sed.
25


10

로 어떻게 표시 ^[입니다 하지 ^[; 또는에 ESC의해 생성 된 ASCII 문자입니다 . 표기법은 Ctrl 키를 의미합니다.EscCtrl[^

ESC사용 할 수 있도록 0x1B 16 진수 또는 033 진수이며, \x1B또는 \033당신의 정규 표현식에에서 :

perl -pe 's/\033\[37m//g; s/\033[0m//g'

perl -pe 's/\033\[\d*(;\d*)*m//g'

6

간단한 것을 선호한다면 strip-ansi 모듈을 사용할 수 있습니다 ( Node.js 필요).

$ npm install --global strip-ansi-cli

그런 다음 다음과 같이 사용하십시오.

$ strip-ansi < colors.o

또는 문자열을 전달하십시오.

$ strip-ansi '^[[37mABC^[[0m'

이것은 쓸모없는 cat( UUOC ) 사용- strip-ansi colors.o적어도 가능하다 strip-ansi < colors.o.
Scott

1
@Scott Sure, 당신도 할 수 strip-ansi < colors.o있지만 경험을 통해 사람들은 배관에 더 익숙합니다. 답변을 업데이트했습니다.
Sindre Sorhus

좋은 간단한 해결책
21:48의 Penghe Geng


2

"응답 된"질문이 저에게 효과가 없었으므로,이 정규 표현식을 작성하여 perl Term :: ANSIColor 모듈에 의해 생성 된 이스케이프 시퀀스를 제거했습니다.

cat colors.o | perl -pe 's/\x1b\[[^m]+m//g;

Grawity의 정규 표현식은 정상적으로 작동하지만 +를 사용하면 정상적으로 작동하는 것으로 보입니다.


4
(1) 무슨 뜻 The "answered" question입니까? 허용 된 답변을 의미합니까? (2)이 명령은 불일치 (불균형) 따옴표가 있기 때문에 작동하지 않으며 실행조차도 불가능합니다. (3) 이것은 쓸모없는 cat( UUOC ) 사용 이 가능해야한다 . (4) 누가 파일 에있는 코드에 대해 말한 적이 있습니까? perl -pe command colors.o.o
Scott

2

나는 이것이 모든 ANSI 이스케이프 시퀀스를 권위있게 제거한다고 생각합니다 .

perl -pe '
  s/\e\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]//g;
  s/\e[PX^_].*?\e\\//g;
  s/\e\][^\a]*(?:\a|\e\\)//g;
  s/\e[\[\]A-Z\\^_@]//g;'

(수용, (하지만 나오지 않음) 다른 언어처럼, 그 펄을 유의하시기 바랍니다 \e이스케이프 문자로 Esc, \x1b또는 \033같은 단말기에 표시된 코드 ^[가 더 직관적 인 것 때문에. 내가 여기를 사용하고 있습니다.)

원하는 경우 한 줄에서 모두 실행할 수있는이 perl 명령에는 다음과 같은 네 가지 대체 항목이 있습니다.

첫 번째는 CSI 시퀀스 (의 "제어 시퀀스 소개서"로 시작하는 이스케이프 코드 시퀀스입니다 ( 컬러 코드 및 기타 텍스트 장식을 구성 Esc[하는 Select Graphic Rendition 시퀀스 보다 훨씬 많은 것을 포함 )).

두 번째 대체는 후행 문자와 관련된 나머지 시퀀스를 제거하고 ST (문자열 종결 자 Esc\)로 종료 합니다. 세 번째 교체 같은 일뿐만 아니라 수 있습니다 운영 체제 명령 시퀀스가 함께 종료 BEL ( \x07, \007, 자주 \a).

네 번째 교체는 나머지 탈출을 제거합니다.

또한 BEL과 같은 다른 폭이 0 인 ASCII 문자 및 기타 더 모호한 C0 및 C1 제어 문자를 제거하십시오 . 내가 사용하고 s/[\x00-\x1f\x7f-\x9f\xad]+//g또한 포함, 삭제소프트 하이픈 . 이 유니 코드의 높은 코드 제로 폭 문자를 제외하지만 난 그것을 ASCII (유니 코드에 대한 철저한하다고 생각 \x00- \xff). 이렇게하면 더 긴 시퀀스에 관련 될 수 있으므로 마지막을 제거하십시오.


1

"tput sgr0"은이 제어 문자를 남겼습니다 ^ (B ^ [
여기에이를 처리하기 위해 수정 된 버전이 있습니다.

perl -pe 's/\e[\[\(][0-9;]*[mGKFB]//g' logfile.log

고마워요 ... tput sgr0다른 솔루션으로는 절대 제거 할 수없는 것으로 제거되었습니다.
TxAG98

0

퍼티를 통해 대화 형 상단 출력을 수집하여 추가 된 문자를 제거하는 것과 비슷한 문제가 있었고 이것은 도움이되었습니다.

cat putty1.log | perl -pe 's/\x1b.*?[mGKH]//g'

3
이것은 쓸모없는 cat( UUOC ) 사용 이 가능합니다 . perl -pe command putty1.log
Scott

0

이것이 나를 위해 일한 것입니다 (Mac OS X에서 테스트 됨)

perl -pe 's/\[[0-9;]*[mGKF]//g'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.