Grep được tô màu - xem toàn bộ tập tin với các kết quả được tô sáng


509

Tôi thấy grep's --color=alwayscờ là vô cùng hữu ích. Tuy nhiên, grep chỉ in các dòng có khớp (trừ khi bạn yêu cầu các dòng ngữ cảnh). Cho rằng mỗi dòng nó in có khớp nhau, phần tô sáng không bổ sung nhiều khả năng nhất có thể.

Tôi thực sự muốn catmột tệp và xem toàn bộ tệp có mẫu phù hợp được tô sáng.

Có cách nào để tôi có thể bảo grep in mọi dòng đang đọc bất kể có khớp không? Tôi biết tôi có thể viết một tập lệnh để chạy grep trên mỗi dòng của tệp, nhưng tôi tò mò liệu điều này có khả thi với tiêu chuẩn không grep.


1
nếu bạn muốn có nhiều hơn một màu cho nhiều hơn một mẫu (ví dụ như thông báo lỗi, cảnh báo, thông tin, v.v.), hãy sử dụngsed . các sedgiải pháp giúp bạn nhiều màu sắc với chi phí thêm phức tạp (thay vì khoảng 30 ký tự mà bạn có khoảng 60 ký tự).
Trevor Boyd Smith

Với sed, bạn thậm chí có thể đánh dấu + trả lại mã thoát , xem ví dụ: askubfox.com/a/1200851/670392
Noam Manos

Câu trả lời:


797

Dưới đây là một số cách để làm điều đó:

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

152
Đó là $ lừa là gọn gàng! Làm tốt lắm, tôi sẽ phải nhớ điều đó. Đối với những người không hiểu biết về biểu thức chính quy, "mẫu | $" sẽ khớp với các dòng có mẫu bạn đang tìm kiếm các dòng AND có kết thúc - đó là tất cả chúng. Bởi vì phần cuối của một dòng không thực sự là bất kỳ ký tự nào, phần được tô màu của đầu ra sẽ chỉ là mẫu của bạn. Cảm ơn Ryan!
zslayton

55
Bạn cũng có thể bỏ qua "$": egrep --color "pattern|" file(tín dụng stackoverflow.com/a/7398092/50979 )
13ren

15
@Zack, "|" toán tử là toán tử OR, không phải là AND,
JBoy

16
@JBoy, tôi đã sử dụng 'VÀ' theo cách tiếng Anh thông thường thay vì cách logic boolean. Bạn đã đúng, đây thực sự là một toán tử 'hoặc' - nó khớp với cái này và cái kia. : P Làm rõ tốt.
zslayton

12
Có vẻ như "$" là cần thiết nếu khớp nhiều hơn một mẫu. egrep --color "pattern1|pattern2|$". Nếu không, việc tô sáng màu không xảy ra.
ZaSter

91

Đây là một cái gì đó dọc theo cùng một dòng. Rất có thể, dù sao bạn cũng sẽ sử dụng ít hơn, vì vậy hãy thử điều này:

less -p pattern file

Nó sẽ làm nổi bật mô hình và chuyển đến lần xuất hiện đầu tiên của nó trong tệp.


4
Cũng hoạt động với đường ống (đọc từ xếp hạng) bằng cách sử dụng -:… | less -p pattern -
phk

3
@phk: Bạn thậm chí có thể bỏ qua dấu gạch ngang.
Tạm dừng cho đến khi có thông báo mới.

Ngoài ra, thêm -itùy chọn sẽ làm cho trường hợp khớp không nhạy cảm như trong less -ip pattern file.
steveb

... và nếu đường ống trong đầu vào có màu ANSI, hãy cung cấp lesscông -Rtắc:… | less -Rip introduction -
Abdull

48

Tôi muốn giới thiệu ack - tốt hơn grep, một công cụ tìm kiếm năng lượng cho các lập trình viên .

$ ack --color --passthru --pager = "$ {PAGER: -less -R}" tệp mẫu
$ ack - tập tin mẫu màu --passthru | ít -R
$ xuất ACK_PAGER_COLOR = "$ {PAGER: -less -R}"
$ ack - tập tin mẫu -passthru

Tôi thích nó vì nó mặc định tìm kiếm đệ quy các thư mục (và thông minh hơn nhiều so với grep -r), hỗ trợ các biểu thức chính quy Perl đầy đủ (chứ không phải POSIXish regex(3)) và hiển thị ngữ cảnh đẹp hơn nhiều khi tìm kiếm nhiều tệp.


2
Tuy nhiên, theo thời gian, nó không tìm thấy những gì tôi muốn khi tôi chắc chắn nó phải ở đó. acklà thông minh, nhưng đôi khi quá thông minh, và nó loại trừ loại tệp mà bản hit đã có.
Michael Piefel

4
@MPi ack -asẽ tìm kiếm tất cả các loại tập tin, trong khi vẫn trừ .git/ .svn/, vv
ephemient

1
Tuy nhiên, thật tuyệt khi ackkhông tìm kiếm thông qua hình ảnh của tôi, -aquá nhiều. Tôi đã thêm --type-set=freemarker=.ftlvào của tôi ~/.ackrc, để đưa ra một ví dụ.
Michael Piefel

3
Với một vài điều chỉnh cấu hình, grep đã thực hiện mọi thứ ack làm, nhanh hơn và không bao giờ bỏ qua kết quả như danh sách trắng của ack đôi khi làm. Có lẽ lưu cài đặt grep ưa thích của bạn trong .bashrc. Của tôi đọc: function grp () {GREP_OPTIONS = "- rI --color --exclude-dir = \. Git --exclude = tags" grep "$ @"
Jonathan Hartley

22

Bạn có thể sử dụng highlighttập lệnh của tôi từ https://github.com/kepkin/dev-shell-essentials

Tốt hơngrepvì bạn có thể làm nổi bật mỗi trận đấu bằng màu sắc riêng của nó .

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

Ảnh chụp màn hình từ dự án Github


3
Câu hỏi rõ ràng yêu cầu một giải pháp sử dụng grep, đó là một tiện ích tiêu chuẩn trên các máy chạy * nix.
zslayton

1
Kịch bản này là tốt, nhưng không tốt như coloutđược đề cập trong một câu trả lời khác.
Jonathan Hartley

@JonathanHartley Và tại sao lại như vậy? Tôi thấy không có lý do cho nó. Bên cạnh đó, tập lệnh này sử dụng một triển khai đơn giản hơn nhiều colout, điều này tốt nếu bạn muốn kiểm tra những gì nó làm.
HelloGoodbye

@Hellooodbye Vâng, đủ công bằng. Tôi nên giữ sự phán xét. colout là kỹ lưỡng và mạnh mẽ hơn, nhưng bạn đúng rằng nó phức tạp hơn để sử dụng và kỹ sư đảo ngược.
Jonathan Hartley

@JonathanHartley Thật ý nghĩa khi nó mạnh hơn!
HelloGoodbye

19

Bạn cũng có thể tạo một bí danh. Thêm chức năng này trong .bashrc của bạn (hoặc .bash_profile trên osx)

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

Bây giờ bạn có thể sử dụng bí danh như thế này: " ifconfig | grepe inet" hoặc " grepe css index.html".

(PS: đừng quên source ~/.bashrctải lại bashrc vào phiên hiện tại)


bạn cũng có thể sử dụng chỉ sử dụng egrep nếu nó có sẵn trên hệ thống của bạn.
Tom

1
Đường ống kết quả của điều này để ít mất thông tin màu sắc. Làm thế nào bạn sẽ ngăn chặn điều đó?
Connor Clark

5
@Hoten sử dụng --color=alwaysthay vì--color
limp_chimp

3
Và, để thực hiện lessviệc giải thích mã màu, sử dụng less -R.
Eliah Kagan

Việc sử dụng $ 2 không được trích dẫn không an toàn. Trong một bash, tôi muốn thực hiện chức năng grepe () {local pattern = "$ 1" shift egrep --color "$ pattern | ^" "$ @"} Xin lỗi vì sự lộn xộn định dạng.
Robert Klemme

16

Sử dụng coloutchương trình: http://nojhan.github.io/colout/

Nó được thiết kế để thêm các màu nổi bật vào luồng văn bản. Đưa ra một biểu thức chính quy và màu sắc (ví dụ "màu đỏ"), nó tái tạo một luồng văn bản với các kết quả khớp được tô sáng. ví dụ:

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

Bạn có thể xâu chuỗi nhiều lệnh để thêm nhiều màu nổi bật khác nhau:

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

Hoặc bạn có thể đạt được điều tương tự bằng cách sử dụng biểu thức chính quy với N nhóm (các phần được ngoặc đơn của biểu thức chính quy), theo sau là danh sách N màu được phân tách bằng dấu phẩy.

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

1
Như đã lưu ý ở nơi khác, câu hỏi rõ ràng yêu cầu một giải pháp sử dụng grep, đây là một tiện ích tiêu chuẩn trên các máy chạy * nix.
zslayton

4
@Zack ok, xin lỗi. Trên thực tế, nếu bạn mở rộng vấn đề ra ngoài grep, và nó đã được mở rộng trong các câu trả lời, coloutlà giải pháp tốt nhất cho vấn đề bạn gặp phải, điều tốt nhất mà tôi biết. Theo triết lý UNIX, các chương trình nên được viết để làm tốt một việc. Đối với grepnó là lọc dòng văn bản. Đối với coloutnó là tô màu hoặc làm nổi bật dòng văn bản.
dùng2683246

Đây là câu trả lời tốt nhất, bởi vì nó có thể áp dụng nhiều điểm nổi bật màu khác nhau, và coloutlà một công cụ hữu ích rộng rãi như vậy. Học nó một lần, sử dụng nó trong nhiều tình huống, thay vì học một công cụ để làm nổi bật các logfiles, một công cụ khác để làm nổi bật đầu ra thử nghiệm, v.v.
Jonathan Hartley

9

Tôi sử dụng RCg từ "Linux Server Hacks", O'Reilly. Nó hoàn hảo cho những gì bạn muốn và có thể làm nổi bật nhiều biểu thức với mỗi màu khác nhau.

#!/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
}

7

Các -zlựa chọn cho grep cũng khá trơn!

cat file1 | grep -z "pattern"

Doe này làm gì? -z bảo grep sử dụng ASCII NUL làm dấu phân cách dòng ...
vy32

6

Tôi đã thêm nó vào .bash_aliases của tôi:

highlight() {
  grep --color -E "$1|\$"
}

3

Để làm nổi bật các mẫu trong khi xem toàn bộ tập tin, h có thể làm điều này.

Thêm vào đó, nó sử dụng các màu sắc khác nhau cho các mẫu khác nhau.

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

Bạn cũng có thể dẫn đầu ra của hđể less -Rđọc tốt hơn.

Để grep và sử dụng 1 màu cho mỗi mẫu, cxpgrep có thể phù hợp.


1

Ok, đây là một cách,

wc -l filename

sẽ cung cấp cho bạn số dòng - nói NN, sau đó bạn có thể làm

grep -C NN --color=always filename

3
"-C 2147483647" nếu bạn không muốn wc trước. Sử dụng một số lượng lớn ở đây dường như không làm mọi thứ chậm lại.
barrycarter

1

Dưới đây là tập lệnh shell sử dụng chức năng gsub của Awk để thay thế văn bản bạn đang tìm kiếm bằng chuỗi thoát thích hợp để hiển thị nó bằng màu đỏ tươi:

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

Sử dụng nó như vậy:

$ ./cgrep pattern [file]

Thật không may, nó không có tất cả các chức năng của grep.

Để biết thêm thông tin, bạn có thể tham khảo một bài viết " So You Like Color " trên Tạp chí Linux


1

Một câu trả lời khác đề cập đến công tắc -Cn của grep bao gồm n dòng ngữ cảnh. Đôi khi tôi làm điều này với n = 99 như một cách nhanh chóng và bẩn thỉu để nhận được [ít nhất] một màn hình bối cảnh khi mẫu egrep có vẻ quá khó, hoặc khi tôi đang sử dụng máy mà tôi chưa cài đặt RCg và / hoặc ccze.

Gần đây tôi đã phát hiện ra cczeđó là một công cụ tô màu mạnh mẽ hơn. Khiếu nại duy nhất của tôi là nó được định hướng theo màn hình (như less, cái mà tôi không bao giờ sử dụng vì lý do đó) trừ khi bạn chỉ định công tắc -A cho đầu ra "ANSI thô".

+1 cho rcgđề cập ở trên. Nó vẫn là sở thích của tôi vì nó rất đơn giản để tùy chỉnh trong một bí danh. Một cái gì đó như thế này thường có trong ~ / .bashrc của tôi:

bí danh tailc = 'tail -f / my / app / log / file | RCg gửi "BÓNG XANH" nhận được lỗi "CYAN" "ĐỎ" '


1

một cách bẩn thỉu khác:

grep -A80 -B80 --color FIND_THIS IN_FILE

Tôi đã làm một

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

trong bashrc.


1
Đây là vấn đề nếu những thứ bạn đang tìm kiếm không có ở đó. Nói do lỗi, trong trường hợp đó bạn sẽ không nhận được gì.
Paul Rubel


0

Nếu bạn muốn làm nổi bật một số mẫu với các màu khác nhau, hãy xem cái này tập lệnh bash .

Cách sử dụng cơ bản:

echo warn error debug info 10 nil | colog

Bạn có thể thay đổi mẫu và màu sắc trong khi chạy nhấn một phím và sau đó nhập phím.


0

Tôi sử dụng lệnh sau cho mục đích tương tự:

grep -C 100 searchtext file

Điều này sẽ nói grep để in 100 * 2 dòng ngữ cảnh, trước và sau văn bản tìm kiếm được tô sáng.


0

Đây là cách tiếp cận của tôi , lấy cảm hứng từ giải pháp của @ 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[@]}")
}

Điều này chấp nhận nhiều đối số (nhưng không cho phép bạn tùy chỉnh màu sắc). Thí dụ:

$ noisy_command | highlight ERROR WARN

-1

Có cách nào để tôi có thể bảo grep in mọi dòng đang đọc bất kể có khớp không?

Tùy chọn -C999sẽ thực hiện thủ thuật trong trường hợp không có tùy chọn để hiển thị tất cả các dòng ngữ cảnh. Hầu hết các biến thể grep khác cũng hỗ trợ này. Tuy nhiên: 1) không có đầu ra nào được tạo ra khi không tìm thấy kết quả khớp và 2) tùy chọn này có tác động tiêu cực đến hiệu quả của grep: khi -Cgiá trị này lớn, nhiều dòng có thể phải được lưu trữ tạm thời trong bộ nhớ cho grep để xác định dòng nào của ngữ cảnh để hiển thị khi trận đấu xảy ra. Lưu ý rằng việc triển khai grep không tải các tệp đầu vào mà chỉ đọc một vài dòng hoặc sử dụng cửa sổ trượt trên đầu vào. "Phần trước" của bối cảnh phải được giữ trong một cửa sổ (bộ nhớ) để xuất các dòng ngữ cảnh "trước" sau khi tìm thấy kết quả khớp.

Một mẫu như ^|PATTERNhoặc PATTERN|$hoặc bất kỳ mẫu phụ phù hợp trống nào cho vấn đề đó, chẳng hạn như [^ -~]?|PATTERNlà một mẹo hay. Tuy nhiên, 1) các mẫu này không hiển thị các dòng không khớp được tô sáng làm bối cảnh và 2) không thể sử dụng kết hợp này với một số tùy chọn grep khác, chẳng hạn như -F-wchẳng hạn.

Vì vậy, không có cách tiếp cận nào trong số này là thỏa mãn với tôi. Tôi đang sử dụng ugrep và grep nâng cao với tùy chọn -yđể hiển thị hiệu quả tất cả đầu ra không khớp dưới dạng các dòng ngữ cảnh được tô màu. Các công cụ giống như grep khác như ag và ripgrep cũng cung cấp tùy chọn chuyển qua. Nhưng ugrep tương thích với GNU / BSD grep và cung cấp một siêu các tùy chọn grep như -y-Q. Ví dụ: đây là tùy chọn -yhiển thị khi kết hợp với -Q(UI truy vấn tương tác để nhập mẫu):

ugrep -Q -y FILE ...

Tại sao bỏ phiếu này mà không để lại nhận xét? Thật công bằng khi đề cập đến các công cụ grep thay thế, giống như một số câu trả lời khác.
Tiến sĩ Alex RE
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.