Colorized grep - ดูไฟล์ทั้งหมดด้วยการจับคู่ที่ไฮไลต์


509

ฉันพบgrep's--color=alwaysธงที่จะเป็นประโยชน์อย่างมาก อย่างไรก็ตาม grep พิมพ์เฉพาะบรรทัดที่มีการจับคู่เท่านั้น (ยกเว้นกรณีที่คุณขอบรรทัดบริบท) เนื่องจากแต่ละบรรทัดที่พิมพ์มีการจับคู่การไฮไลต์ไม่ได้เพิ่มความสามารถให้มากที่สุดเท่าที่จะทำได้

ฉันต้องการcatไฟล์จริงๆและดูไฟล์ทั้งหมดที่มีการจับคู่รูปแบบที่เน้นไว้

มีวิธีที่ฉันสามารถบอก grep ให้พิมพ์ทุกบรรทัดที่อ่านไม่ว่าจะมีการแข่งขันหรือไม่? ฉันรู้ว่าฉันสามารถเขียนสคริปต์เพื่อรัน grep ในทุกบรรทัดของไฟล์ แต่ฉันอยากรู้ว่าสิ่งนี้เป็นไปได้ด้วยมาตรฐานgrepหรือไม่


1
ถ้าคุณต้องการมากกว่าหนึ่งสีสำหรับรูปแบบมากกว่าหนึ่ง (เช่นข้อผิดพลาดคำเตือนข้อมูลข้อความ ฯลฯ ), การใช้งาน sedการsedแก้ปัญหาทำให้คุณมีหลายสีในราคาที่เพิ่มความซับซ้อน (แทนที่จะเป็นประมาณ 30 ตัวอักษรคุณมีประมาณ 60 ตัวอักษร)
เทรเวอร์บอยด์สมิ ธ

ด้วยsedคุณยังสามารถเน้นรหัสทางออกผลตอบแทน + , ดูตัวอย่าง: askubuntu.com/a/1200851/670392
โนม Manos

คำตอบ:


797

นี่คือวิธีที่จะทำ:

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

152
นั่นคือ | เคล็ดลับ $ เรียบร้อย! ทำได้ดีมากฉันจะต้องจำไว้ สำหรับบรรดาของคุณที่ไม่เข้าใจการแสดงออกปกติ "pattern | $" จะจับคู่บรรทัดที่มีรูปแบบที่คุณกำลังค้นหาและบรรทัดที่มีจุดสิ้นสุด - นั่นคือพวกเขาทั้งหมด เนื่องจากจุดสิ้นสุดของบรรทัดไม่ใช่อักขระใด ๆ จริง ๆ ส่วน colorized ของผลลัพธ์จะเป็นรูปแบบของคุณ ขอบคุณ Ryan!
zslayton

55
นอกจากนี้คุณยังสามารถละเว้น "$": egrep --color "pattern|" file(credit stackoverflow.com/a/7398092/50979 )
13ren

15
@Zack, "|" ตัวดำเนินการเป็นตัวดำเนินการ OR ไม่ใช่ AND,
JBoy

16
@JBoy ฉันใช้ 'AND' ในภาษาอังกฤษแบบดั้งเดิมมากกว่าทางตรรกะแบบบูล คุณถูกต้องมันเป็นตัวดำเนินการ 'หรือ' - มันตรงกับสิ่งนี้และสิ่งนั้น : P ชี้แจงดี
zslayton

12
ดูเหมือนว่าจำเป็นต้องใช้ "$" หากจับคู่มากกว่าหนึ่งรูปแบบ egrep --color "pattern1|pattern2|$". มิฉะนั้นการไฮไลต์สีจะไม่เกิดขึ้น
ZaSter

91

นี่คือบางสิ่งในแนวเดียวกัน โอกาสที่คุณจะใช้งานน้อยลงดังนั้นให้ลองทำดังนี้:

less -p pattern file

มันจะเน้นรูปแบบและข้ามไปที่การเกิดขึ้นครั้งแรกในไฟล์


4
สามารถใช้งานกับ piping (อ่านจาก stding) โดยใช้-:… | less -p pattern -
phk


นอกจากนี้ยังมีการเพิ่มตัวเลือกที่จะทำให้ความรู้สึกกรณีที่การแข่งขันในขณะที่-i less -ip pattern file
steveb

... และถ้า piping ในอินพุต ANSI ที่มีสีให้lessกับ-Rสวิตช์:… | less -Rip introduction -
Abdull

48

ฉันอยากจะแนะนำack - ดีกว่า grep เครื่องมือค้นหาพลังงานสำหรับโปรแกรมเมอร์เป็นเครื่องมือในการค้นหาพลังงานสำหรับโปรแกรมเมอร์

$ ack --color --passthru --pager = "$ {PAGER: -less -R}" ไฟล์ลวดลาย
$ ack --color --passthru รูปแบบไฟล์ | น้อยกว่า -R
$ export ACK_PAGER_COLOR = "$ {PAGER: -less -R}"
$ ack - รูปแบบไฟล์ passthru

ฉันรักมันเพราะค่าเริ่มต้นคือการค้นหาไดเรกทอรีซ้ำ ๆ (และทำให้ชาญฉลาดกว่ามาก grep -r ) สนับสนุนการแสดงออกปกติของ Perl แบบเต็ม (แทนที่จะเป็น POSIXish regex(3)) และมีการแสดงบริบทที่ดีกว่าเมื่อค้นหาไฟล์จำนวนมาก


2
อย่างไรก็ตามบางครั้งก็ไม่พบสิ่งที่ฉันต้องการเมื่อฉันแน่ใจว่ามันจะต้องมี ackฉลาด แต่บางครั้งก็ฉลาดเกินไปและยกเว้นประเภทไฟล์ที่มีการเข้าชม
Michael Piefel

4
@MPi ack -aจะค้นหาไฟล์ทุกประเภทในขณะที่ยังไม่รวม.git/ .svn/ฯลฯ
ephemient

1
อย่างไรก็ตามมันเจ๋งมากที่ackไม่ได้ค้นหาภาพของฉันดังนั้น-aทำมากเกินไป ฉันเพิ่ม--type-set=freemarker=.ftlของฉัน~/.ackrcเพื่อยกตัวอย่างหนึ่ง
Michael Piefel

3
ด้วยการปรับแต่ง config สองสามครั้ง grep ก็ทำทุกสิ่งที่แอคทำได้เร็วกว่าและไม่เคยละเว้นผลลัพธ์เช่นบัญชีขาวของแอ๊ทำบางครั้ง อาจบันทึกการตั้งค่า grep ที่คุณต้องการใน. bashrc Mine อ่าน: ฟังก์ชั่น grp () {GREP_OPTIONS = "- rI --color --exclude-dir = \. git --exclude = แท็ก" grep "$ @"
Jonathan Hartley

22

คุณสามารถใช้highlightสคริปต์ของฉันจากhttps://github.com/kepkin/dev-shell-essentials

มันเป็นเรื่องที่ดีกว่ากว่าgrepเพราะคุณสามารถไฮไลต์การแข่งขันแต่ละครั้งกับสีของตัวเอง

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

สกรีนช็อตจากโครงการ Github


3
คำถามจะถามอย่างชัดเจนถึงวิธีการแก้ปัญหาโดยใช้grepซึ่งเป็นยูทิลิตี้มาตรฐานบนเครื่องที่ใช้ * ระวัง
zslayton

1
สคริปต์นี้ดี แต่ไม่ดีเท่าที่coloutกล่าวไว้ในคำตอบอื่น
Jonathan Hartley

@JonathanHartley และทำไมถึงเป็นเช่นนั้น? ฉันไม่เห็นเหตุผลเลย นอกจากนี้สคริปต์นี้ใช้การปรับใช้ที่ง่ายกว่าcoloutซึ่งจะดีถ้าคุณต้องการตรวจสอบสิ่งที่ทำ
HelloGoodbye

@HelloGoodbye ใช่ยุติธรรมพอ ฉันควรระงับการตัดสิน colout นั้นละเอียดและมีประสิทธิภาพมากกว่า แต่คุณคิดถูกว่ามันซับซ้อนกว่าในการใช้และ reverse-engineer
Jonathan Hartley

@ 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 ถ้ามันมีอยู่ในระบบของคุณ
Tom

1
การวางท่อผลลัพธ์นี้จะทำให้สูญเสียข้อมูลสีน้อยลง คุณจะป้องกันได้อย่างไร
Connor Clark

5
@Hoten ใช้--color=alwaysแทน--color
limp_chimp

3
และเพื่อให้ตีความรหัสสีที่ใช้less less -R
Eliah Kagan

การใช้ $ 2 โดยไม่อ้างอิงไม่ปลอดภัย ในทุบตีฉันควรทำ grepe () {local pattern = "$ 1" shift egrep --color "$ pattern | ^" "$ @"} ขออภัยในการจัดรูปแบบ
Robert Klemme

16

ใช้coloutโปรแกรม: http://nojhan.github.io/colout/

มันถูกออกแบบมาเพื่อเพิ่มไฮไลท์สีให้กับสตรีมข้อความ ได้รับ regex และสี (เช่น "สีแดง") มันจะทำซ้ำสตรีมข้อความที่มีการจับคู่เน้น เช่น:

# 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

หรือคุณสามารถบรรลุสิ่งเดียวกันโดยใช้ regex กับกลุ่ม N (ส่วนวงเล็บของ regex) ตามด้วยรายการที่คั่นด้วยจุลภาคของสี N

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

1
ตามที่ระบุไว้ที่อื่นคำถามจะถามอย่างชัดเจนถึงวิธีการใช้ grep ซึ่งเป็นยูทิลิตี้มาตรฐานสำหรับเครื่องที่ใช้ * ระวัง
zslayton

4
@ แจ็คโอเคขอโทษ ที่จริงแล้วถ้าคุณขยายปัญหาเกินกว่าgrepนั้นและมันขยายออกไปในคำตอบแล้วcoloutทางออกที่ดีที่สุดสำหรับปัญหาที่คุณมีคือสิ่งที่ดีที่สุดที่ฉันรู้ ตามปรัชญาของ UNIX ควรเขียนโปรแกรมเพื่อทำสิ่งหนึ่งที่ดี เพราะgrepมันคือการกรองกระแสข้อความ เพราะcoloutมันเป็น colorizing หรือเน้นข้อความสตรีม
2683246

นี่คือคำตอบที่ดีที่สุดเพราะสามารถใช้ไฮไลท์สีที่แตกต่างกันหลายและcoloutเป็นเครื่องมือที่มีประโยชน์อย่างกว้างขวาง เรียนรู้ครั้งเดียวใช้มันในหลาย ๆ สถานการณ์แทนที่จะเรียนรู้เครื่องมือหนึ่งเพื่อไฮไลต์ไฟล์บันทึกอีกหนึ่งไฟล์เพื่อเน้นผลการทดสอบ ฯลฯ
Jonathan Hartley

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
}

7

-zตัวเลือกสำหรับการ grep ยังเป็นเนียนสวย!

cat file1 | grep -z "pattern"

สิ่งนี้ทำอะไร -z บอก grep ให้ใช้ ASCII NUL เป็นตัวคั่นบรรทัด ...
vy32


3

เพื่อเน้นรูปแบบในขณะที่ดูไฟล์ทั้งหมดhสามารถทำได้

นอกจากนี้ยังใช้สีที่แตกต่างสำหรับรูปแบบที่แตกต่างกัน

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

คุณยังสามารถไพพ์เอาท์พุทของเป็นhเพื่อless -Rให้อ่านได้ดีขึ้น

หากต้องการ grep และใช้ 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

สำหรับข้อมูลเพิ่มเติมคุณสามารถอ้างอิงบทความ " So You Like Color " ใน Linux Journal


1

อีกหนึ่งคำตอบที่กล่าวถึงสวิตช์ -Cn ของ grep ซึ่งมี n บรรทัดของบริบท บางครั้งฉันทำสิ่งนี้โดยใช้ n = 99 เป็นวิธีที่รวดเร็วและสกปรกในการรับ [อย่างน้อย] screenfull ของบริบทเมื่อรูปแบบ egrep ดูเหมือนเที่ยวยุ่งยิ่งเกินไปหรือเมื่อฉันอยู่บนเครื่องที่ฉันไม่ได้ติดตั้ง rcg และ / หรือ ccze

ฉันเพิ่งค้นพบcczeซึ่งเป็น colorizer ที่มีประสิทธิภาพมากขึ้น ข้อร้องเรียนอย่างเดียวของฉันคือมันเป็นหน้าจอ (เช่นlessที่ฉันไม่เคยใช้ด้วยเหตุผลนั้น) เว้นแต่คุณจะระบุสวิตช์ -A สำหรับเอาต์พุต "raw ANSI"

+1 สำหรับการrcgกล่าวถึงข้างต้น มันยังคงเป็นที่ชื่นชอบของฉันเพราะมันง่ายในการปรับแต่งในนามแฝง สิ่งนี้มักจะอยู่ใน ~ / .bashrc ของฉัน:

alias tailc = 'tail -f / my / app / log / file | rcg ส่ง "BOLD GREEN" รับ "CYAN" ข้อผิดพลาด "RED" '


1

อีกวิธีที่สกปรก:

grep -A80 -B80 --color FIND_THIS IN_FILE

ฉันทำ

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

ใน bashrc


1
นี่เป็นปัญหาหากสิ่งที่คุณต้องการไม่อยู่ที่นั่น พูดเนื่องจากข้อผิดพลาดซึ่งในกรณีนี้คุณจะไม่ได้รับอะไรเลย
Paul Rubel


0

หากคุณต้องการเน้นหลายรูปแบบด้วยสีที่แตกต่างกันดูนี้สคริปต์ทุบตี

การใช้งานขั้นพื้นฐาน:

echo warn error debug info 10 nil | colog

คุณสามารถเปลี่ยนรูปแบบและสีในขณะที่กดปุ่มเดียวแล้วกดปุ่ม


0

ฉันใช้คำสั่งต่อไปนี้เพื่อจุดประสงค์ที่คล้ายกัน:

grep -C 100 searchtext file

สิ่งนี้จะบอกว่า grep พิมพ์บรรทัดบริบท 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เพื่อแสดงผลลัพธ์ที่ไม่ตรงกันทั้งหมดอย่างมีประสิทธิภาพเป็นเส้นบริบทที่เน้นสี เครื่องมือเช่น grep อื่น ๆ เช่น ag และ ripgrep ยังมีตัวเลือก pass-through อีกด้วย แต่ ugrep เข้ากันได้กับ GNU / grep BSD และข้อเสนอ superset ของตัวเลือก grep เหมือนและ-y -Qตัวอย่างเช่นนี่คือสิ่งที่ตัวเลือก-yจะแสดงเมื่อรวมกับ-Q(UI แบบสอบถามแบบโต้ตอบเพื่อป้อนรูปแบบ):

ugrep -Q -y FILE ...

ลงคะแนนทำไมลงโดยไม่แสดงความคิดเห็น? เป็นมากกว่าการพูดถึงเครื่องมือ grep ทางเลือกเช่นเดียวกับคำตอบอื่น ๆ
ดร. อเล็กซ์ RE
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.