Фільтр виведення команди за кольором


13

Я запускаю утиліту, яка не пропонує способу фільтрації її результатів. Ніщо в тексті виводу не вказує на те, що певна функція не вдалася, але вона відображається червоним кольором. Вихід настільки довгий, що наприкінці, коли він повідомляє про кілька помилок, я не завжди можу прокручувати, щоб побачити вихід, де сталася помилка.

Як я можу відфільтрувати не червоний текст?

псевдо-код:

dolongtask | grep -color red

Редагувати

Команда виводить інші кольори , а також і мені потрібно , щоб мати можливість фільтрувати поза весь текст, НЕ червоного кольору. Також розмальовки тексту є багаторядковими.


1
Прошу вибачення за запитання очевидного - але весь вихід увімкнено >&1? Тобто, червоний матеріал не згасне, якщо ти 2>/dev/null, правда?
mikeserv

Відповіді:


15

Перемикання кольору здійснюється за допомогою послідовностей, що вбудовуються в текст. Незмінно програми видають послідовності виходу ANSI , тому що саме зараз підтримують практично всі термінали.

Послідовність виходу для перемикання кольору переднього плану на червоний - це \e[31mде \eпозначає символ втечі (восьмеричний 033, шістнадцятковий 1b, також відомий як ESC, ^[та інші інші позначення). Цифри в діапазоні 30–39 задають колір переднього плану; інші числа задають різні атрибути. \e[0mскидає всі атрибути до їх значення за замовчуванням. Запустіть, cat -vщоб перевірити, що програма друкує, вона може використовувати якийсь варіант, такий як \e[0;31mспочатку скинути всі атрибути або \e[3;31також увімкнути курсив (який багато термінали не підтримують).

У ksh, bash або zsh ви можете використовувати $'…'для ввімкнення зворотної косої риски всередині лапок, що дозволяє вводити $'\e'символ для втечі. Зауважте, що потім вам доведеться подвоїти будь-яку зворотну косу рису, яку ви хочете пройти grep. В /bin/sh, ви можете використовувати "$(printf \\e)"або введіть буквальний екранує символ.

За допомогою grep -oпараметра GNU наступний фрагмент фільтрує червоний текст, припускаючи, що він починається з послідовності запуску \e[31m, закінчується одним \e[0mабо одним і \e[30mтим же рядком і не містить вбудованої послідовності втечі.

grep -Eo $'\e\\[31m[^\e]*\e\\[[03]?m'

Наступний awkфрагмент витягує червоний текст, навіть якщо він є багаторядковим.

awk -v RS='\033' '
    match($0, /^\[[0-9;]*m/) {
        color = ";" substr($0, 2, RLENGTH-2) ";";
        $0 = substr($0, RLENGTH+1);
        gsub(/(^|;)0*[^03;][0-9]*($|;)/, ";", color);
        red = (color ~ /1;*$/)
    }
    red'

Ось варіант, який зберігає команди зміни кольору, які можуть бути корисні, якщо ви фільтруєте кілька кольорів (тут червоний і пурпурний).

awk -v RS='\033' '
    match($0, /^\[[0-9;]*m/) {
        color = ";" substr($0, 2, RLENGTH-2) ";";
        printf "\033%s", substr($0, 1, RLENGTH);
        $0 = substr($0, RLENGTH+1);
        gsub(/(^|;)0*[^03;][0-9]*($|;)/, ";", color);
        desired = (color ~ /[15];*$/)
    }
    desired'

Рішення awk працювало на мене. Будь-який спосіб зберегти колір у виході?
km6zla

@ ogc-nick Ви хочете все-червоний вихід? printf '\e[31m'; awk …; printf '\e[0m'
Жил 'ТАК - перестань бути злим'

Якраз для будь-якого кольору, який я фільтрую, для збереження у висновку.
km6zla

@ ogc-nick Дивіться мою редагування.
Жил 'ТАК - перестань бути злим'

6

Ви можете мати гарний пошук контрольних символів, деякі з яких відповідають за створення красивих кольорів на терміналі.

dolongtask | grep '[[:cntrl:]]'

Наприклад, це перегукується з червоним "тестом" на grep, який виявляє це завдяки тому, що він оточений контрольними символами:

$ echo -e '\033[00;31mtest\033[00m' | grep --color=none '[[:cntrl:]]'
test     <-- in red

Потрібно --color=noneлише переконатися, що grep не застосовує власну забарвлення до відповідного виводу, але друкує всю лінійку вірно, щоб контрольні символи були інтерпретовані оболонкою.


Приємно. Цікаво, чи можна було б піти далі і зробити щось на кшталт grep -E $'\033\[0?[01];31m.+?\033\[0?0m'або grep -Po '\033\[0?[01]+;31m\K.+?(?=\033\[0?0m)'випробувати тестування на червоне?
steeldriver

Я почав придумувати реджекси, як ті, які ви пропонуєте, але, перш ніж я міг змусити їх працювати, я наткнувся [[:cntrl:]]. Я тестував твої, і вони працюють на мене, тобто. збіг червоного та невідповідний іншим кольорам.
савато

Чудово працює, але буде відповідати будь-якому кольору. Я не згадував це в питанні, але багато інших кольорів також виходять, і я просто хочу побачити червоний матеріал. +1 для простого та робочого коду.
km6zla
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.