ANSI renk kodlarını metin akışından kaldırma


73

Çıkışının incelenmesi

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

Bir metin editöründe (örneğin, vi) aşağıdakileri gösterir:

^[[37mABC
^[[0m

ANSI renk kodları çıktı dosyasından nasıl kaldırılır? Sanırım en iyi yol çıktıyı bir tür akış düzenleyiciden geçirmektir.

Aşağıdaki çalışmıyor

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

Sorunun cevabı değil, çıktıyı ayrıca bir metin editörü yerine, çıkış kodlarını renkli olarak değerlendirebilir moreveya less -Ryönlendirebilirsiniz.
terdon

Yanıtlar:


97

Karakterler ^[[37mve ANSI çıkış dizilerinin bir^[[0m parçasıdır (CSI kodları) . Ayrıca bu özelliklere bakın .

GNU’yu kullanma sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b(veya \x1B) kaçış özel karakteridir
    ( sedalternatifleri desteklemez \eve \033)
  • \[ kaçış dizisinin ikinci karakteri
  • [0-9;]* renk değerleri regex
  • m kaçış dizisinin son karakteri

OS MacOS'ta, varsayılan sedkomut , yorumlardaki slm ve vapur25 ile\e gösterilen özel karakterleri desteklemez . Kullanarak kurabileceğiniz yerine kullanın .gsedbrew install gnu-sed

OP'nin komut satırına örnek:   (OP Orijinal Poster anlamına gelir)

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] , sadece mgrafik moduna (renkli) kaçış sırasına özgü harf yerine, tüm diğer kaçış dizilerinin kaldırılmasını önerir . Ancak [a-zA-Z]çok geniş olabilir ve çok fazla kaldırabilir. Michał Faleński ve Miguel Mota sırasıyla [mGKH]ve bazılarını kullanarak yalnızca bazı kaçış dizilerini kaldırmayı teklif ediyor [mGKF]. Britton Kerin , renkleri hata / uyarıdan kaldırmak için Kek olarak kullanılması gerektiğini de belirtir (yönlendirmeyi unutmayın ).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

kullanma perl

sedBazı işletim sistemlerinde kurulu sürümü sınırlı olabilir (örneğin, macOS). Komut perl, daha fazla işletim sistemine kurulması / güncellenmesi genellikle daha kolay olma avantajına sahiptir. Adam Katz kullanımını önerir \e(Aynı durum \x1bolarak) PCRE'nin .

Düzenlemek istediğiniz komuta bağlı olarak regex'inizi seçin:

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'nin komut satırı ile örnek:

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

kullanım

Stuart Cardall'un yorumunun işaret ettiği gibi , bu sedkomut satırı e-posta raporunu temizlemek için Ultimate Nginx Bad Bot (1000 yıldız) projesi tarafından kullanılır ;-)


2
sedKomut ve açıklama için teşekkürler . :)
Redsandro

2
Bazı renk kodları (örn. Linux terminali) bir önek içerir, örneğin 1;31mregex'inize daha iyi ekleyin ;: cat colored.log | sed -r 's/\x1b\[[0-9;]*m//g'yoksa soyulmayacaklar.
Redsandro

1
bu, e-posta raporunu temizlemek için github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/blob/… adresinde kullanılması mükemmeldir .
Stuart Cardall

2
OSX sürümünün, sedgösterilen örnekle çalışmadığını, gsedancak sürümün çalıştığını unutmayın .
slm

2
Slm'nin OSX sed hakkındaki yorumu için daha fazla içerik: \ x1b gibi kontrol karakterlerini desteklemiyor. Örneğin, stackoverflow.com/a/14881851/93345 . Gsed komutunu üzerinden alabilirsiniz brew install gnu-sed.
vapur25


10

Olarak nedir görüntülenir ^[olduğu değil ^ ve [; bu, ASCII ESCkarakteri tarafından üretilir Escveya Ctrl[( ^notasyon Ctrl tuşu anlamına gelir).

ESC0x1B onaltılık veya 033 sekizlik olduğundan, kullanmak \x1Bveya \033regex'lerde kullanmak zorundasınız :

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

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

6

Basit bir şey tercih ediyorsanız, strip-ansi modülünü kullanabilirsiniz ( Node.js gereklidir):

$ npm install --global strip-ansi-cli

Öyleyse şöyle kullan:

$ strip-ansi < colors.o

Veya sadece bir dizgeye geçin:

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

Bu işe yaramaz bir kullanım cat( UUOC ) - yapmak mümkün olmalı strip-ansi colors.oveya en azından strip-ansi < colors.o.
Scott,

1
@Scott Tabii ki de yapabilirsiniz strip-ansi < colors.o, ancak deneyimlerden insanlar boruları daha iyi bilirler. Cevabı güncelledim.
Sindre Sorhus

iyi basit bir çözüm
Penghe Geng


2

"Cevap" sorusu benim için işe yaramadı, bu yüzden perge Term tarafından üretilen kaçış dizilerini kaldırmak yerine bu regex'i yarattım: ANSIColor modülü.

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

Grawity'nin regex'i düzgün çalışmalı, fakat + 'nın kullanılması da iyi çalışıyor gibi görünüyor.


4
(1) Ne demek istiyorsun The "answered" question? Kabul edilen cevabı mı kastediyorsun? (2) Bu komut çalışmıyor - bile çalışmıyor - benzersiz (dengesiz) bir alıntı var. (3) Bu cat( UUOC ) yararsız bir kullanım - yapmak mümkün olmalıdır . (4) Kodların dosyada olduğu hakkında kim bir şey söyledi ? perl -pe command colors.o.o
Scott,

2

Bunun tüm ANSI kaçış dizilerinin yetkili bir şekilde kaldırılması olduğuna inanıyorum :

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;'

(Kabul, (ancak sed değil) birçok diğer diller gibi, bu perl unutmayın \ekaçış karakteri olarak Esc, \x1bya \033olduğu gibi terminaller gösterilen kod tarafından ^[daha sezgisel görünüyor çünkü. Ben burada kullanıyorum.)

İsterseniz hepsini tek bir satırda çalıştırabileceğiniz bu perl komutu, içinde dört değişikliğe sahiptir:

Birincisi, CSI dizilerinin ( renk kodlarını ve diğer metin süslemelerini oluşturan Grafik Seçimi Dizileri Seç dizisindenEsc[ çok daha fazlasını kapsayan "Kontrol Dizisi Girişimi" ile başlayan kaçış kodu dizileri) peşinden gider .

İkinci değiştirme, takip eden karakterleri içeren ve ST ile sonlanan (Dize Terminator Esc\) kalan dizileri kaldırır . Üçüncü yedek aynı şeydir aynı zamanda sağlar İşletim Sistemi Komuta dizileri ile biten etmek BEL ( \x07, \007genellikle \a).

Dördüncü değiştirme kalan kaçışları giderir.

Ayrıca BEL gibi diğer sıfır genişliğindeki ASCII karakterlerini ve diğer daha belirsiz olan C0 ve C1 kontrol karakterlerini kaldırmayı da düşünün . Ben kullanıyorum s/[\x00-\x1f\x7f-\x9f\xad]+//gda içerir ki, Sil ve Kesme İşareti . Bu Unicode'un yüksek kodlanmış sıfır genişlikli karakterlerini içermez, ancak ASCII (Unicode \x00- \xff) için ayrıntılı olduğuna inanıyorum . Bunu yaparsanız, daha uzun sekanslarda yer alabildiklerinden bunları son kaldırın.


1

"tput sgr0" bu kontrol karakterinden ayrıldı ^ (B ^ [
Burada dikkat edilmesi gereken değiştirilmiş bir sürüm.

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

Bunun için teşekkürler ... bu tput sgr0, diğer çözümlerin asla kurtulacak gibi görünmediğinden kurtulmam için çalıştı .
TxAG98

0

Ben de etkileşimli üst çıktıyı macunla toplamaktan eklenen karakterleri kaldırmakla aynı sorunu yaşadım ve bu yardımcı oldu:

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

3
Bu işe yaramaz bir kullanım cat( UUOC ) - yapmak mümkün olmalıdır . perl -pe command putty1.log
Scott,

0

Bu benim için çalıştı (Mac OS X'te test edilmiştir).

perl -pe 's/\[[0-9;]*[mGKF]//g'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.