Кольоровий греп - перегляд всього файлу з виділеними відповідністю


509

Я вважаю , grep«s --color=alwaysпрапор , щоб бути надзвичайно корисним. Однак, grep друкує лише рядки зі збігами (якщо ви не запитуєте контекстні рядки). Зважаючи на те, що кожен надрукований рядок має відповідність, виділення не додає стільки можливостей, скільки можливо.

Мені б дуже хотілося, щоб catфайл переглянув весь файл із відповідним шаблоном.

Чи я можу сказати grep, щоб надрукувати кожен прочитаний рядок незалежно від відповідності? Я знаю, що можу написати сценарій для запуску grep у кожному рядку файлу, але мені було цікаво, чи це можливо за допомогою стандарту grep.


1
якщо вам потрібно більше одного кольору для більш ніж одного шаблону (тобто повідомлення про помилку, попередження, інформацію тощо), використовуйтеsed . sedрішення отримує вас кілька кольорів за рахунок додаткової складності (замість приблизно 30 символів , що мають близько 60 символів).
Тревор Бойд Сміт

За допомогою sed можна навіть виділити + повернути вихідний код , див. Приклад: askubuntu.com/a/1200851/670392
Ноам Манос

Відповіді:


797

Ось кілька способів зробити це:

grep --color -E 'pattern|$' file
grep --color 'pattern\|$' file
egrep --color 'pattern|$' file

152
Що | $ трюк акуратний! Молодці, я мушу це пам’ятати. Для тих із вас, хто не має правильного вираження, "pattern | $" буде відповідати рядкам, які мають шаблон, який ви шукаєте, і рядкам, які мають кінець - тобто всім. Оскільки кінець рядка насправді не є жодними символами, кольорова частина виводу буде просто вашим шаблоном. Дякую, Райан!
zslayton

55
Ви також можете опустити «$»: egrep --color "pattern|" file(кредит stackoverflow.com/a/7398092/50979 )
13ren

15
@Zack, "|" Оператор - АБО оператор, А не І,
JBoy

16
@JBoy, я використовував "AND" звичайним англійським способом, а не булевим логічним способом. Ви маєте рацію, це дійсно оператор "чи" - він відповідає цьому і тому. : P Хороше уточнення.
zslayton

12
Здається, що "$" потрібен, якщо збігається більше ніж один шаблон. egrep --color "pattern1|pattern2|$". Інакше виділення кольорів не відбувається.
ZaSter

91

Ось щось у цьому ж руслі. Швидше за все, ви все одно будете використовувати менше, тому спробуйте це:

less -p pattern file

Він виділить шаблон і перейде до першого появи його у файлі.


4
Також працює з трубопроводами (читання з stding), використовуючи -:… | less -p pattern -
phk

3
@phk: Ви навіть можете пропустити тире.
Призупинено до подальшого повідомлення.

Крім того, додавання -iпараметра зробить регістр відповідності нечутливим, як у випадку less -ip pattern file.
steveb

... і якщо конвеєр в ANSI-кольоровий введенні, забезпечує lessз -Rперемикачем:… | less -Rip introduction -
Abdull

48

Я хотів би порекомендувати ack - краще, ніж grep - інструмент пошуку потужності для програмістів .

$ ack --color --passthru --pager = "$ {PAGER: -less -R}" файли шаблонів
$ ack --кольорові --пастхру файли шаблонів | менше -R
$ export ACK_PAGER_COLOR = "$ {PAGER: -less -R}"
$ ack - файли шаблону

Мені подобається, тому що він за замовчуванням здійснює рекурсивний пошук каталогів (і робить його набагато розумнішим, ніж grep -r), підтримує повноцінні регулярні вирази Perl (а не POSIXish regex(3)) і має набагато приємніше відображення контексту при пошуку багатьох файлів.


2
Однак час від часу він не знаходить того, чого я хочу, коли впевнений, що він повинен бути там. ackрозумний, але іноді занадто розумний, і він виключав тип файлу, в який потрапив хіт.
Майкл Піфель

4
@MPi здійснить ack -aпошук усіх типів файлів, виключаючи .git/ .svn/і т.д.
ephemient

1
Однак, це круто, що ackне шукає моїх зображень, тому -aзанадто багато. Я додав --type-set=freemarker=.ftlдо свого ~/.ackrc, щоб навести один приклад.
Майкл Пієфель

3
За допомогою декількох налаштувань, grep вже робить все, що робить, швидше, і ніколи не опускає результатів, як це іноді роблять білі списки Ack. Можливо, збережіть бажані налаштування grep в .bashrc. Шахта читає: функція grp () {GREP_OPTIONS = "- rI --color --exclude-dir = \. Git --exclude = теги" grep "$ @"
Джонатан Хартлі

22

Ви можете використовувати мій highlightсценарій із https://github.com/kepkin/dev-shell-essentials

Це краще, ніж grepтому, що ви можете виділити кожен матч своїм кольором .

$ command_here | highlight green "input" | highlight red "output"

Знімок екрана від проекту Github


3
Питання прямо вимагає рішення з використанням grep, яка є стандартною утилітою для машин, що працюють * nix.
zslayton

1
Цей сценарій хороший, але не такий хороший, як coloutзгадується в іншій відповіді.
Джонатан Хартлі

@JonathanHartley І чому це так? Я не бачу причин для цього. Крім того, цей сценарій використовує набагато простішу реалізацію, ніж це colout, що добре, якщо ви хочете перевірити, що він робить.
HelloGoodbye

@HelloGoodbye Так, досить справедливо. Я повинен би відмовитися від рішення. Колоут є більш ретельним і потужним, але ви маєте рацію, що відповідно використовувати його і реверс-інженер.
Джонатан Хартлі

@JonathanHartley Має сенс, що він є більш потужним!
HelloGoodbye

19

Ви також можете створити псевдонім. Додайте цю функцію у свій .bashrc (або .bash_profile на osx)

function grepe {
    grep --color -E "$1|$" $2
}

Тепер ви можете використовувати псевдонім на зразок цього: " ifconfig | grepe inet" або " grepe css index.html".

(PS: не забудьте source ~/.bashrcперезавантажити bashrc на поточному сеансі)


ви також можете просто використовувати egrep, якщо він доступний у вашій системі.
Том

1
Перекочуючи результат, це менше втрачає інформацію про колір. Як би ви запобігли цьому?
Коннор Кларк

5
@Hoten використання --color=alwaysзамість--color
limp_chimp

3
І, щоб зробити lessінтерпретацію кольорових кодів, використовуйте less -R.
Елія Каган

Використання котирувань у розмірі 2 доларів не є безпечним. У баші я скоріше виконую функцію grepe () {local pattern = "$ 1" shift egrep --color "$ pattern | ^" "$ @"} Вибачте за невдачу форматування.
Роберт Клемме

16

Використовуйте coloutпрограму: http://nojhan.github.io/colout/

Він призначений для додавання кольорових виділень до текстового потоку. З огляду на регулярний вираз та колір (наприклад, "червоний"), він відтворює текстовий потік із виділеними відповідністю. наприклад:

# cat logfile but highlight instances of 'ERROR' in red
colout ERROR red <logfile

Ви можете пов’язати кілька викликів, щоб додати кілька різних кольорових виділень:

tail -f /var/log/nginx/access.log | \
    colout ' 5\d\d ' red | \
    colout ' 4\d\d ' yellow | \
    colout ' 3\d\d ' cyan | \
    colout ' 2\d\d ' green

Або ви можете домогтися того ж, скориставшись регулярними виразами з N груп (круглі дужки частин регулярного виразів) з подальшим комою списком N кольорів.

vagrant status | \
    colout \
        '\''(^.+  running)|(^.+suspended)|(^.+not running)'\'' \
        green,yellow,red

1
Як було зазначено в іншому місці, питання прямо вимагає рішення за допомогою grep, що є стандартною утилітою на машинах, що працюють * nix.
zslayton

4
@Zack добре, вибачте. Насправді, якщо розгорнути проблему за grepїї межами , і вона вже розширена у відповідях, coloutце найкраще рішення проблеми, яку ви мали, найкраще, про що я знаю. Відповідно до філософії UNIX, програми повинні бути написані для того, щоб зробити одну справу добре. Адже grepце фільтрація текстового потоку. Бо coloutце розфарбування або виділення текстового потоку.
user2683246

Це найкраща відповідь, оскільки вона може застосовувати кілька кольорових яскравих кольорів, і coloutє таким широко корисним інструментом. Вивчіть це один раз, використовуйте його в багатьох ситуаціях, а не вивчайте один інструмент для виділення логін, інший для виділення тестових результатів тощо.
Джонатан Хартлі

9

Я використовую rcg від "Linux Server Hacks", O'Reilly. Він ідеально підходить для того, що ви хочете, і може виділити кілька виразів, кожен з яких відрізняється кольорами.

#!/usr/bin/perl -w
#
#       regexp coloured glasses - from Linux Server Hacks from O'Reilly
#
#       eg .rcg "fatal" "BOLD . YELLOW . ON_WHITE"  /var/adm/messages
#
use strict;
use Term::ANSIColor qw(:constants);

my %target = ( );

while (my $arg = shift) {
        my $clr = shift;

        if (($arg =~ /^-/) | !$clr) {
                print "Usage: rcg [regex] [color] [regex] [color] ...\n";
                exit(2);
        }

        #
        # Ugly, lazy, pathetic hack here. [Unquote]
        #
        $target{$arg} = eval($clr);

}

my $rst = RESET;

while(<>) {
        foreach my $x (keys(%target)) {
                s/($x)/$target{$x}$1$rst/g;
        }
        print
}



3

Щоб виділити шаблони під час перегляду всього файлу, h може це зробити.

Крім того, він використовує різні кольори для різних візерунків.

cat FILE | h 'PAT1' 'PAT2' ...

Ви також можете передавати висновок hдля less -Rдля кращого читання.

Щоб зімкнути та використати 1 колір для кожного візерунка, cxpgrep може бути гарним підходом .


1

Гаразд, це один із способів,

wc -l filename

дасть вам кількість рядків - скажімо, NN, тоді ви можете зробити

grep -C NN --color=always filename

3
"-C 2147483647", якщо ви не хочете першим користувачем. Використання великої кількості тут, здається, не сповільнить справи.
barrycarter

1

Ось скрипт оболонки, який використовує функцію gsub Awk для заміни тексту, який ви шукаєте, на відповідну послідовність втечі, щоб відобразити його яскраво-червоним:

#! /bin/bash
awk -vstr=$1 'BEGIN{repltext=sprintf("%c[1;31;40m&%c[0m", 0x1B,0x1B);}{gsub(str,repltext); print}' $2

Використовуйте його так:

$ ./cgrep pattern [file]

На жаль, він не має всіх функціональних можливостей grep.

Для отримання додаткової інформації ви можете ознайомитися зі статтею " Так вам подобається колір " у Linux Journal


1

В іншій відповіді згаданий перемикач grep's -Cn, який включає n рядків контексту. Я іноді роблю це з n = 99 як швидкий і брудний спосіб отримати [принаймні] скриншот контексту, коли шаблон egrep здається занадто химерним, або коли я перебуваю на машині, на якій я не встановив rcg та / або ccze.

Нещодавно я виявив, cczeщо є більш потужним колоризатором. Моя єдина скарга на те, що вона орієнтована на екран (наприклад less, який я ніколи не використовую з цієї причини), якщо не вказати перемикач -A для вихідного "необробленого ANSI".

+1 для rcgзгадки вище. Він досі є моїм улюбленим, оскільки його так просто налаштувати в псевдонімі. Щось подібне зазвичай є в моєму ~ / .bashrc:

псевдонім tailc = 'хвіст -f / my / app / log / файл | rcg відправити "BOLD GREEN" отримати "CYAN" помилку "RED" '


1

ще один брудний спосіб:

grep -A80 -B80 --color FIND_THIS IN_FILE

Я зробив

alias grepa='grep -A80 -B80 --color'

у bashrc.


1
це проблематично, якщо речей, які ви шукаєте, немає. Скажіть через помилку, і в цьому випадку ви нічого не отримаєте.
Пол Рубель


0

Якщо ви хочете виділити кілька візерунків з різними кольорами, дивіться це сценарій баш.

Основне використання:

echo warn error debug info 10 nil | colog

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


0

Я використовую таку команду для подібних цілей:

grep -C 100 searchtext file

Це дозволить надрукувати друк 100 * 2 рядка контексту до і після виділеного тексту пошуку.


0

Ось мій підхід , натхненний рішенням @ kepkin:

# Adds ANSI colors to matched terms, similar to grep --color but without
# filtering unmatched lines. Example:
#   noisy_command | highlight ERROR INFO
#
# Each argument is passed into sed as a matching pattern and matches are
# colored. Multiple arguments will use separate colors.
#
# Inspired by https://stackoverflow.com/a/25357856
highlight() {
  # color cycles from 0-5, (shifted 31-36), i.e. r,g,y,b,m,c
  local color=0 patterns=()
  for term in "$@"; do
    patterns+=("$(printf 's|%s|\e[%sm\\0\e[0m|g' "${term//|/\\|}" "$(( color+31 ))")")
    color=$(( (color+1) % 6 ))
  done
  sed -f <(printf '%s\n' "${patterns[@]}")
}

Це приймає кілька аргументів (але не дозволяє налаштувати кольори). Приклад:

$ noisy_command | highlight ERROR WARN

-1

Чи я можу сказати grep, щоб надрукувати кожен прочитаний рядок незалежно від відповідності?

Опція -C999зробить трюк за відсутності можливості відображення всіх рядків контексту. Більшість інших варіантів grep також підтримують це. Однак: 1) вихід не виробляється, коли не знайдено збігу, і 2) цей параметр негативно впливає на ефективність grep: коли -Cзначення велике, можливо, багато рядків, можливо, доведеться тимчасово зберігати в пам'яті для grep, щоб визначити, які рядки контексту відображатись, коли відбувається збіг. Зауважте, що реалізація grep не завантажує вхідні файли, а читає кілька рядків або використовує розсувне вікно над входом. Контекст "до частини" повинен зберігатися у вікні (пам'яті), щоб виводити рядки контексту "до" пізніше, коли буде знайдено збіг.

Шаблон, наприклад, ^|PATTERNабо PATTERN|$будь-який підкадрування з порожнім узгодженням для цього питання, такий як [^ -~]?|PATTERNхороший трюк. Однак 1) ці шаблони не показують невідповідні рядки, виділені як контекст, і 2) це не можна використовувати в поєднанні з деякими іншими варіантами grep, такими як -Fі-w , наприклад.

Тож жоден із цих підходів мене не влаштовує. Я використовую ugrep та посилений grep з можливістю -yефективно відображати всі невідповідні результати як кольорові виділені контекстні лінії. Інші інструменти, подібні до грепу, такі як ag та ripgrep, також пропонують можливість проходу. Але ugrep сумісний з GNU / BSD grep та пропонує безліч варіантів grep, таких як -yі -Q. Наприклад, ось, що -yвідображається у поєднанні з -Q(інтерактивний інтерфейс запиту для введення шаблонів):

ugrep -Q -y FILE ...

Навіщо голосувати за це, не залишаючи коментарів? Більш ніж справедливо згадати альтернативні інструменти грепування, як і деякі інші відповіді.
Д-р Алекс РЕ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.