2013-02-06 9 views
6

Grep konusuna nasıl saygı duyarım? Borulu çıktıyı dağıtırken ANSI rengi kaçıyor mu? Grep yerine başka bir şey (perl?) Kullanmaktan mutluluk duyuyorum.grep renkli metinden, örn. gcc | colorgcc | grep regexp

Benim usercase: I (ANSI kaçar kullanarak bir unix terminal üzerine) renklerle güzel

gcc foobar.c | colorgcc | grep regexp 
ls --color | grep filename 

çalışmalarını istiyorum.

echo -e "he\e[35mllo\e[00m" world |grep hell ==> he\e[35mllo\e[00m world 
echo -e "\e[35m removed line\nhello\e[00m" world |grep hell ==> \e[35mhello\e[00m world 
echo -e "\e[35m rem\e[1moved line\nhello\e[00m" world | grep hell ==> \e35m\e1mhello\e[00m world 

anda ilk satırı boş bir dize verir ve ikinci bir uncolorised dize 'merhaba \ e [00m dünyanın verir: davranış

Test örnekleri istediğim. Burada [35m ve \ e00m renk (öznitelik) modifiye edicidir: bir mektubun rengi, son birkaç renk (öznitelik) kaçış dizileri tarafından belirlenir \ e [P1; P2; P1, P2 vb. basamaklar dizisidir; \ e [P1m \ e [P2m \ e [P1; P2m 'ye eşdeğerdir. \ e [0m, rengi varsayılan yapar ve önceki tümleri unutacaktır. [..m dizileri: \ e [34m \ e [0m, \ e [0m. Birkaç bağımsız özellik vardır (cesaret, arka planın rengi, ön planın/harfin rengi); Bir çıkış sırasındaki her sayı, bunlardan sadece birini etkiler. Böylece \ e [1m \ e [35m, \ e [1; 35m'ye eşdeğerdir, ancak [e [35; 1m ve \ e [35m; bununla birlikte, [34m \ e [35m, e [35m'dir. Çünkü ikisi de aynı telaşı etkiler (harf/foregrnound'un rengi).

+2

İlk bıçak: Burada

egrep versiyonu colorgcc | daha az -R +/regexp'. daha az -R renk kodlarını anlar ve etraflarında arama yapar. – nneonneo

cevap

2

Bu gerçekten ilginç bir sorundur, işte işte burada. Oldukça çirkin ama işin yapılması için görünüyor:

sed -n '1s/^/\x1b[0m/;H;x;s/\n//;p;s/.*\(\x1b\[[0-9]*m\(;[0-9]*m\)*\).*/\1/;h' | 
    grep `sed 's/./\0\\\\(\x1b\\\\[[0-9]*m\\\\(;[0-9]*m\\\\)*\\\\)*/g' <<< hell` 

siz ("cehennem" yerine) en sonunda gelebileceğini söyledi arıyor terim, burada metin ile birkaç örnek

$ echo -e "he\e[35mllo\e[00m" world | 
> sed -n '1s/^/\x1b[0m/;H;x;s/\n//;p;s/.*\(\x1b\[[0-9]*m\(;[0-9]*m\)*\).*/\1/;h' | 
> grep `sed 's/./\0\\\\(\x1b\\\\[[0-9]*m\\\\(;[0-9]*m\\\\)*\\\\)*/g' <<< hell` | 
> hexdump -C 
00000000 1b 5b 30 6d 68 65 1b 5b 33 35 6d 6c 6c 6f 1b 5b |.[0mhe.[35mllo.[| 
00000010 30 30 6d 20 77 6f 72 6c 64 0a     |00m world.| 
0000001a 

$ echo -e "\e[35m removed line\nhello\e[00m" world | 
> sed -n '1s/^/\x1b[0m/;H;x;s/\n//;p;s/.*\(\x1b\[[0-9]*m\(;[0-9]*m\)*\).*/\1/;h' | 
> grep `sed 's/./\0\\\\(\x1b\\\\[[0-9]*m\\\\(;[0-9]*m\\\\)*\\\\)*/g' <<< hell` | 
> hexdump -C 
00000000 1b 5b 33 35 6d 68 65 6c 6c 6f 1b 5b 30 30 6d 20 |.[35mhello.[00m | 
00000010 77 6f 72 6c 64 0a         |world.| 
00000016 

ilk sed komutu renk grep bir hat üzerinde yer almaktadır ikinci örnek için gerekli olan her satırın başında, mevcut renk ayarı prepends: Eğer (renkleri göstermek için HexDump kullanarak) sağlanan atlayacak. Grep argümanı olan sed komutu, arama terimindeki her karakter arasındaki herhangi bir sayıda renk kaçışına uyan bir regex ekler. | `Gcc foobar.c: Bir çözüme

sed -n '1s/^/\x1b[0m/;H;x;s/\n//;p;s/.*\(\x1b\[[0-9]*m\(;[0-9]*m\)*\).*/\1/;h' | 
    egrep `sed 's/./\0(\x1b\\\\[[0-9]*m(;[0-9]*m)*)*/g' <<< hell` 
+0

Teşekkürler! Bu doğru çalışmıyor: echo -e "\ e [35m kaldırıldı \ e [0m satır \ nh \ e [34mel \ e [32mlo \ e [00m" –

+0

oh üzgünüm! hayır, bu iyi çalışıyor. ama keyfi regexps ile çalışır? 'Grep' yerine 'egrep' ile değiştirdiğimde işe yaramıyor gibi görünmüyor –

+0

Eğer grep'i egrep ile değiştirirseniz, tüm ters eğik çizgileri, '(' ya da ')' dan hemen önce gelen ikinci sed komutuyla kaldırabilirsiniz. . Bunu bir düzenlemeye ekledik. –