Grep berwarna - melihat seluruh file dengan kecocokan yang disorot

509

Saya menemukan grep's --color=alwaysbendera untuk menjadi sangat berguna. Namun, grep hanya mencetak garis dengan kecocokan (kecuali jika Anda meminta garis konteks). Mengingat bahwa setiap baris yang dicetak memiliki kecocokan, penyorotan tidak menambah kemampuan sebanyak mungkin.

Saya benar-benar ingin catsebuah file dan melihat seluruh file dengan kecocokan pola yang disorot.

Apakah ada cara saya dapat memberitahu grep untuk mencetak setiap baris yang sedang dibaca terlepas dari apakah ada kecocokan? Saya tahu saya bisa menulis skrip untuk menjalankan grep pada setiap baris file, tetapi saya ingin tahu apakah ini mungkin dengan standar grep.

zslayton
sumber
1
jika Anda ingin lebih dari satu warna untuk lebih dari satu pola (mis. pesan kesalahan, peringatan, info, dll), gunakansed . yang sedsolusi membuat Anda beberapa warna pada biaya tambahan kompleksitas (bukan dari sekitar 30 karakter Anda memiliki sekitar 60 karakter).
Trevor Boyd Smith
Dengan sed Anda bahkan dapat menyorot + mengembalikan kode keluar , lihat contoh: askubuntu.com/a/1200851/670392
Noam Manos

Jawaban:

797

Berikut ini beberapa cara untuk melakukannya:

grep --color -E 'pattern|$' file
grep --color 'pattern\|$' file
egrep --color 'pattern|$' file
Ryan Oberoi
sumber
152
Trik $ | itu rapi! Bagus, saya harus ingat itu. Bagi Anda yang tidak memahami ekspresi reguler, "pattern | $" akan cocok dengan garis yang memiliki pola yang Anda cari DAN garis yang memiliki akhir - yaitu, semuanya. Karena akhir baris sebenarnya bukan karakter apa pun, bagian keluaran yang berwarna hanya akan menjadi pola Anda. Ryan terima kasih!
zslayton
55
Anda juga dapat menghilangkan "$": egrep --color "pattern|" file(credit stackoverflow.com/a/7398092/50979 )
13ren
15
@Zack, "|" operator adalah operator ATAU, bukan AND,
JBoy
16
@JBoy, saya menggunakan 'DAN' dalam cara bahasa Inggris konvensional daripada cara logika boolean. Anda benar, ini memang operator 'atau' - cocok dengan ini dan itu. : P Klarifikasi yang baik.
zslayton
12
Tampaknya "$" diperlukan jika cocok dengan lebih dari satu pola. egrep --color "pattern1|pattern2|$". Kalau tidak, penyorotan warna tidak akan terjadi.
ZaSter
91

Ada sesuatu di sepanjang baris yang sama. Kemungkinannya adalah, Anda akan menggunakan lebih sedikit, jadi coba ini:

less -p pattern file

Ini akan menyoroti pola dan melompat ke kemunculannya yang pertama dalam file.

Dijeda sampai pemberitahuan lebih lanjut.
sumber
4
Juga bekerja dengan perpipaan (membaca dari stding) menggunakan -:… | less -p pattern -
phk
3
@ phk: Anda bahkan dapat menghilangkan tanda hubung.
Dijeda sampai pemberitahuan lebih lanjut.
Juga, menambahkan -iopsi akan membuat case case tidak sensitif seperti pada less -ip pattern file.
steveb
... dan jika pipa di masukan ANSI-berwarna, memberikan lessdengan -Rswitch:… | less -Rip introduction -
Abdull
48

Saya ingin merekomendasikan ack - lebih baik daripada grep, alat pencarian yang hebat untuk programmer .

$ ack --color --passthru --pager = "$ {PAGER: -less -R}" file pola
$ ack --color --passthru file pola | kurang -R
$ export ACK_PAGER_COLOR = "$ {PAGER: -less -R}"
$ ack --passthru file pola

Saya suka itu karena default untuk pencarian direktori secara rekursif (dan melakukan jauh lebih pintar daripada grep -r), mendukung ekspresi reguler Perl penuh (daripada POSIXish regex(3)), dan memiliki tampilan konteks yang jauh lebih baik ketika mencari banyak file.

singkat
sumber
2
Namun, dari waktu ke waktu, tidak menemukan apa yang saya inginkan ketika saya yakin pasti ada di sana. ackcerdas, tetapi terkadang terlalu cerdas, dan tidak termasuk jenis file yang menjadi sasaran.
Michael Piefel
4
@MPi ack -aakan mencari semua jenis file, sementara masih mengecualikan .git/ .svn/dll.
ephemient
1
Namun, itu keren yang acktidak mencari melalui gambar saya, begitu -ajuga banyak Saya menambahkan --type-set=freemarker=.ftlke saya ~/.ackrc, untuk memberikan satu contoh.
Michael Piefel
3
Dengan beberapa konfigurasi tweak, grep sudah melakukan semua yang dilakukan ack, lebih cepat, dan tidak pernah menghilangkan hasil seperti yang biasanya dilakukan daftar putih ack. Mungkin menyimpan pengaturan grep pilihan Anda di .bashrc. Tambang berbunyi: function grp () {GREP_OPTIONS = "- rI --color --exclude-dir = \. Git --exclude = tag" grep "$ @"
Jonathan Hartley

22

Anda dapat menggunakan highlightskrip saya dari https://github.com/kepkin/dev-shell-essentials

Ini lebih baik daripada grepkarena Anda dapat menyorot setiap pertandingan dengan warnanya sendiri .

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

Tangkapan layar dari proyek Github


3
Pertanyaannya dengan jelas meminta solusi menggunakan grep, yang merupakan utilitas standar pada mesin yang menjalankan * nix.
zslayton

1
Skrip ini bagus, tetapi tidak sebagus yang coloutdisebutkan dalam jawaban lain.
Jonathan Hartley

@ Jonathanathan Hartley Dan mengapa begitu? Saya tidak melihat alasan untuk itu. Selain itu, skrip ini menggunakan implementasi yang jauh lebih sederhana daripada colout, yang bagus jika Anda ingin memeriksa apa fungsinya.
HelloGoodbye

@ HaloGoodbye Ya, cukup adil. Saya harus menunda penghakiman. colout lebih teliti dan kuat, tetapi Anda benar bahwa colout lebih kompleks untuk digunakan dan direkayasa ulang.
Jonathan Hartley

@ JonathanHartley Masuk akal kalau itu lebih kuat!
HelloGoodbye

19

Anda juga dapat membuat alias. Tambahkan fungsi ini di .bashrc Anda (atau .bash_profile di osx)

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

Anda sekarang dapat menggunakan alias seperti ini: " ifconfig | grepe inet" atau " grepe css index.html".

(PS: jangan lupa source ~/.bashrcmemuat ulang bashrc pada sesi saat ini)


Anda juga dapat menggunakan cukup gunakan egrep jika tersedia di sistem Anda.
Tom

1
Perpipaan hasil ini untuk mengurangi kehilangan informasi warna. Bagaimana Anda mencegahnya?
Connor Clark

5
@Hoten gunakan --color=alwaysbukan--color
limp_chimp

3
Dan, untuk membuat lessmenafsirkan kode warna, gunakan less -R.
Eliah Kagan

Penggunaan tanda kutip $ 2 tidak aman kosong. Dalam sebuah bash saya lebih suka melakukan function grepe () {local pattern = "$ 1" shift egrep --color "$ pattern | ^" "$ @"} Maaf untuk kekacauan format.
Robert Klemme
16

Gunakan coloutprogram: http://nojhan.github.io/colout/

Ini dirancang untuk menambahkan highlight warna ke aliran teks. Diberikan regex dan warna (misalnya "merah"), ia mereproduksi aliran teks dengan kecocokan yang disorot. misalnya:

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

Anda dapat membuat beberapa permintaan untuk menambahkan beberapa highlight warna yang berbeda:

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

Atau Anda dapat mencapai hal yang sama dengan menggunakan regex dengan grup N (bagian tanda kurung dari regex), diikuti oleh daftar warna N yang dipisahkan koma.

vagrant status | \
    colout \
        '\''(^.+  running)|(^.+suspended)|(^.+not running)'\'' \
        green,yellow,red
pengguna2683246
sumber
1
Seperti disebutkan di tempat lain, pertanyaan tersebut secara tegas menanyakan solusi menggunakan grep, yang merupakan utilitas standar pada mesin yang menjalankan * nix.
zslayton
4
@ Zack ok, maaf. Sebenarnya, jika Anda memperluas masalah di luar grep, dan itu sudah diperluas dalam jawaban, coloutadalah solusi terbaik untuk masalah yang Anda miliki, yang terbaik yang saya sadari. Menurut filosofi UNIX, program harus ditulis untuk melakukan satu hal dengan baik. Untuk grepitu menyaring aliran teks. Untuk coloutitu mewarnai atau menyoroti aliran teks.
user2683246
Ini adalah jawaban terbaik, karena dapat menerapkan beragam highlight berwarna, dan coloutmerupakan alat yang sangat berguna. Pelajari sekali, gunakan dalam banyak situasi, daripada belajar satu alat untuk menyoroti file log, yang lain untuk menyoroti hasil tes, dll.
Jonathan Hartley
9

Saya menggunakan rcg dari "Linux Server Hacks", O'Reilly. Ini sempurna untuk apa yang Anda inginkan dan dapat menyorot banyak ekspresi masing-masing dengan warna yang berbeda.

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

The -zpilihan untuk grep juga cukup licin!

cat file1 | grep -z "pattern"
Abhishek Jaisingh
sumber
apa yang dilakukan ini? -z memberitahu grep untuk menggunakan ASCII NUL sebagai pembatas garis ...
vy32
6

Saya menambahkan ini ke .bash_aliases saya:

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

Untuk menyorot pola saat melihat seluruh file, h bisa melakukan ini.

Plus itu menggunakan warna berbeda untuk pola yang berbeda.

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

Anda juga dapat menyalurkan output hke less -Runtuk membaca lebih baik.

Untuk menangkap dan menggunakan 1 warna untuk setiap pola, cxpgrep mungkin cocok.

treulz
sumber
1

Ok, ini satu arah,

wc -l filename

akan memberi Anda jumlah baris - katakan NN, maka Anda bisa melakukannya

grep -C NN --color=always filename
nik
sumber
3
"-C 2147483647" jika Anda tidak ingin wc terlebih dahulu. Menggunakan sejumlah besar di sini tampaknya tidak memperlambat segalanya.
barrycarter
1

Berikut ini adalah skrip shell yang menggunakan fungsi gkub Awk untuk mengganti teks yang Anda cari dengan urutan escape yang tepat untuk menampilkannya dalam warna merah terang:

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

Gunakan seperti ini:

$ ./cgrep pattern [file]

Sayangnya, ia tidak memiliki semua fungsi grep.

Untuk informasi lebih lanjut, Anda dapat merujuk ke artikel " So You Like Color " di Linux Journal

Wernsey
sumber
1

Satu jawaban lain menyebutkan saklar grep's -Cn yang mencakup n baris Konteks. Saya kadang-kadang melakukan ini dengan n = 99 sebagai cara cepat dan kotor untuk mendapatkan [setidaknya] satu layar penuh konteks ketika pola egrep tampak terlalu fiddly, atau ketika saya menggunakan mesin yang belum saya instal rcg dan / atau ccze.

Saya baru-baru ini menemukan cczeyang merupakan pewarna yang lebih kuat. Satu-satunya keluhan saya adalah bahwa itu berorientasi layar (seperti less, yang saya tidak pernah gunakan untuk alasan itu) kecuali Anda menentukan -A switch untuk output "raw ANSI".

+1 untuk rcg disebutkan di atas. Ini masih menjadi favorit saya karena sangat mudah untuk menyesuaikan dalam alias. Sesuatu seperti ini biasanya ada di my ~ / .bashrc:

alias tailc = 'tail -f / my / app / log / file | rcg kirim "BOLD GREEN" terima "CYAN" error "RED" '

MarkHu
sumber
1

cara kotor lain:

grep -A80 -B80 --color FIND_THIS IN_FILE

Saya melakukan

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

dalam bashrc.

fly_a320
sumber
1
ini bermasalah jika hal-hal yang Anda cari tidak ada. Katakan karena kesalahan, dalam hal ini Anda tidak akan mendapatkan apa-apa.
Paul Rubel
0

Jika Anda ingin menyorot beberapa pola dengan warna berbeda, lihat ini skrip bash .

Penggunaan dasar:

echo warn error debug info 10 nil | colog

Anda dapat mengubah pola dan warna sambil menjalankan menekan satu tombol dan kemudian memasukkan tombol.

Edoot
sumber
0

Saya menggunakan perintah berikut untuk tujuan serupa:

grep -C 100 searchtext file

Ini akan mengatakan grep untuk mencetak 100 * 2 baris konteks, sebelum & sesudah teks pencarian yang disorot.

Al Mamun
sumber
0

Inilah pendekatan saya , terinspirasi oleh solusi @ 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[@]}")
}

Ini menerima beberapa argumen (tetapi tidak membiarkan Anda menyesuaikan warna). Contoh:

$ noisy_command | highlight ERROR WARN
dimo414
sumber
-1

Apakah ada cara saya dapat memberitahu grep untuk mencetak setiap baris yang sedang dibaca terlepas dari apakah ada kecocokan?

Opsi -C999akan melakukan trik dengan tidak adanya opsi untuk menampilkan semua baris konteks. Sebagian besar varian grep lainnya mendukung ini juga. Namun: 1) tidak ada output yang dihasilkan ketika tidak ditemukan kecocokan dan 2) opsi ini memiliki dampak negatif pada efisiensi grep: ketika -Cnilainya besar, banyak baris ini mungkin harus disimpan sementara di memori agar grep menentukan garis konteks mana untuk ditampilkan ketika kecocokan terjadi. Perhatikan bahwa implementasi grep tidak memuat file input tetapi membaca beberapa baris atau menggunakan jendela geser di atas input. "Sebelum bagian" dari konteks harus disimpan di jendela (memori) untuk menampilkan baris konteks "sebelum" nanti ketika kecocokan ditemukan.

Pola seperti ^|PATTERNatau PATTERN|$atau setiap sub-pola pencocokan kosong dalam hal [^ -~]?|PATTERNini adalah trik yang bagus. Namun, 1) pola ini tidak menunjukkan garis yang tidak cocok disorot sebagai konteks dan 2) ini tidak dapat digunakan dalam kombinasi dengan beberapa opsi grep lainnya, seperti -Fdan-w misalnya.

Jadi tidak ada pendekatan yang memuaskan saya. Saya menggunakan ugrep , dan grep yang ditingkatkan dengan opsi -yuntuk secara efisien menampilkan semua keluaran yang tidak cocok sebagai garis konteks yang disorot warna. Alat seperti grep lainnya seperti ag dan ripgrep juga menawarkan opsi pass-through. Tetapi ugrep kompatibel dengan grep GNU / BSD dan menawarkan superset opsi grep seperti -ydan -Q. Misalnya, berikut adalah opsi yang -yditampilkan ketika dikombinasikan dengan -Q(UI kueri interaktif untuk memasukkan pola):

ugrep -Q -y FILE ...
Alex RE
sumber
Mengapa memilih ini tanpa meninggalkan komentar? Lebih adil untuk menyebutkan alat grep alternatif, sama dengan beberapa jawaban lainnya.
Dr. Alex RE