彩色grep——用高亮显示的匹配项查看整个文件

我发现grep--color=always标志非常有用。但是,grep只打印匹配的行(除非您要求上下文行)。假设它打印的每一行都有一个匹配项,那么高亮显示并不能增加尽可能多的功能。

我真的很想cat一个文件,并看到整个文件与模式匹配突出显示。

是否有某种方法可以告诉grep打印正在读取的每一行,而不管是否有匹配?我知道我可以编写一个脚本在文件的每一行上运行grep,但我很好奇是否可以使用标准的grep

275304 次浏览

这是一种方法,

wc -l filename

会给你行数,比如NN,你能做什么

grep -C NN --color=always filename

这里有一些方法:

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

|符号是OR运算符。或者使用\转义它,或者通过添加-E或使用egrep命令而不是grep告诉grep搜索文本必须被解释为正则表达式。

搜索文本"pattern|$"实际上是一个技巧,它将匹配有pattern的行或有结束的行。因为所有的行都有一个结尾,所有的行都被匹配,但是一行的结尾实际上不是任何字符,所以它不会被着色。

要通过管道传递有颜色的部分,例如,向less传递,将always参数提供给--color:

grep --color=always 'pattern\|$' file | less -r
grep --color=always -E 'pattern|$' file | less -r
egrep --color=always 'pattern|$' file | less -r

下面是一个shell脚本,它使用Awk的gsub函数来替换你正在搜索的文本,使用正确的转义序列以亮红色显示:

#! /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中的文章“所以你喜欢颜色

这里有一些类似的东西。很有可能,无论如何你都会用得更少,所以试试这个:

less -p pattern file

它将突出显示该模式,并跳转到该模式在文件中第一次出现的位置。

您可以使用n跳转到下一个事件,使用p跳转到前一个事件。使用q退出。

我想推荐Ack—比grep更好,是程序员的强大搜索工具

$ ack --color --passthru --pager="${PAGER:-less -R}" pattern files
$ ack --color --passthru pattern files | less -R
$ export ACK_PAGER_COLOR="${PAGER:-less -R}"
$ ack --passthru pattern files

我喜欢它,因为它默认为递归搜索目录(并且比grep -r聪明得多),支持完整的Perl正则表达式(而不是POSIXish regex(3)),并且在搜索许多文件时具有更好的上下文显示。

我使用的rcg来自“Linux服务器黑客”,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
}

另一个回答提到了grep的-Cn开关,其中包含n行Context。当egrep模式看起来太复杂,或者当我在一台没有安装rcg和/或ccze的机器上时,我有时会用n=99作为一种快速而肮脏的方式来获得[至少]满屏的上下文。

我最近发现ccze是一个更强大的着色剂。我唯一的抱怨是它是面向屏幕的(就像less,我从来没有因为这个原因使用它),除非你为“原始ANSI”输出指定-A开关。

+1为上面提到的rcg。它仍然是我的最爱,因为它是如此简单,自定义在一个别名。类似这样的东西通常在我的~/.bashrc中:

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

另一种肮脏的方式:

grep -A80 -B80 --color FIND_THIS IN_FILE

我做了一个

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

在bashrc。(

您也可以创建别名。在你的.bashrc(或osx上的.bash_profile)中添加这个函数

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

您现在可以像这样使用别名:“ifconfig | grepe inet”或“grepe css index.html”。

(PS:不要忘记source ~/.bashrc重载当前会话bashrc)

你可以使用https://github.com/kepkin/dev-shell-essentials中的highlight脚本

它是更好的而不是grep,因为你可以用自己的颜色突出显示每个匹配。

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

Screen shot from Github project

我把这个添加到我的.bash_aliases中:

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

使用colout程序:http://nojhan.github.io/colout/

它的目的是为文本流添加颜色高亮。给定一个正则表达式和一个颜色(例如:"red"),它会重新生成匹配突出显示的文本流。例句:

# 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

或者,您可以使用银色的探索者并执行

ag <search> --passthrough

如果您想突出显示不同颜色的几个模式,请参阅 bash脚本。

基本用法:

echo warn error debug info 10 nil | colog

你可以改变图案和颜色,同时运行按一键,然后进入键。

要在查看整个文件时突出显示模式,h可以做到这一点。

另外,它使用不同的颜色来代表不同的图案。

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

您还可以将h的输出输送到less -R,以便更好地阅读。

要grep并为每个图案使用一种颜色,cxpgrep可能很适合。

我使用以下命令来达到类似的目的:

# EYZ0

这将说grep打印100 * 2行上下文,在&之后的高亮搜索文本。

grep的-z选项也非常漂亮!

cat file1 | grep -z "pattern"

下面是我的方法,灵感来自@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
是否有某种方法可以告诉grep打印正在读取的每一行 不管是否匹配?< / p >

选项-C999将在没有显示所有上下文行选项的情况下发挥作用。大多数其他grep变体也支持这一点。然而:1)当没有找到匹配时不会产生输出,2)此选项对grep的效率有负面影响:当-C值很大时,可能必须将这么多行暂时存储在内存中,以便grep确定在出现匹配时显示哪些上下文行。请注意,grep实现不加载输入文件,而是读取几行或在输入上使用滑动窗口。上下文的“前部分”必须保存在一个窗口(内存)中,以便稍后在找到匹配时输出“前”上下文行。

^|PATTERNPATTERN|$这样的模式或任何空匹配的子模式(如[^ -~]?|PATTERN)都是一个很好的技巧。然而,1)这些模式不会显示不匹配的行作为上下文突出显示,2)这不能与其他一些grep选项组合使用,例如-F-w

所以这些方法都不能让我满意。我使用ugrep和选项-y的增强型grep,以有效地将所有不匹配的输出显示为彩色高亮的上下文行。其他类似grep的工具,如ag和ripgrep也提供了一个传递选项。但是ugrep与GNU/BSD grep兼容,并提供了grep选项的超集,如-y-Q。例如,下面是-y选项与-Q(交互式查询UI以输入模式)结合时显示的内容:

ugrep -Q -y FILE ...

这看起来像是恶意入侵。

grep "^\|highlight1\|highlight2\|highlight3" filename

这意味着-匹配行(^)或highlight1或highlight2或highlight3的开头。因此,您将高亮显示所有的highlight*模式匹配,甚至在同一行中。

正如grep -E '|pattern'已经建议过的那样,只是想澄清一下,它也可以突出显示一整行。

例如,tail -f somelog | grep --color -E '| \[2\].*'(特别是部分-E '|):

.

使用ripgrep,即rg: https://github.com/BurntSushi/ripgrep

rg - passthru……

颜色是默认的:

enter image description here

  rg -t tf -e  'key.*tfstate' -e dynamodb_table
--passthru
Print both matching and non-matching lines.


Another way to achieve a similar effect is by modifying your pattern to
match the empty string.
For example, if you are searching using rg foo then using
rg "^|foo" instead will emit every line in every file searched, but only
occurrences of foo will be highlighted.
This flag enables the same behavior without needing to modify the pattern.

亵渎神明,没错,但格雷普已经沾沾自喜了。

# EYZ0

你再也回不去了。

方式

因为已经有很多不同的解决方案,但没有显示sed作为解决方案,
因为sedgrep更轻,更快,我更喜欢使用sed来做这种工作:

sed 's/pattern/\o33[47;31;1m&\o033[0m/' file

这似乎不太直观。

  • \o33sed语法,用于生成字符octal 033 -># EYZ3。
    (一些shell和编辑器也允许输入<Ctrl>-<V>后面跟着<Esc>,直接输入字符。
  • Esc [ 47 ; 31 ; 1 m是一个ANSI转义码:背景灰色,前景红色和粗体面。
  • &将重新打印pattern
  • Esc [ 0 m返回默认颜色。

你也可以高亮整行,但是把pattern标记为红色:

sed -E <file -e \
's/^(.*)(pattern)(.*)/\o33[30;47m\1\o33[31;1m\2\o33[0;30;47m\3\o33[0m/'

动态tail -f,跟随日志文件

使用sed的好处之一:你可以在主机上发送报警哔哔声,使用贝尔 ascii字符 0x7。我经常像这样使用sed:

sudo tail -f /var/log/kern.log |
sed -ue 's/[lL]ink .*\([uU]p\|[dD]own\)/\o33[47;31;1m&\o33[0m\o7/'
  • -u代表无缓冲的。所以线条会立即处理。

所以当我连接或断开以太网电缆时,我会听到一些哔哔声。

当然,不是link up模式,你可以在同一个文件中寻找USB,甚至在/var/log/mail.log中搜索from=

也试一试:

# EYZ0

这将为您提供一个带有高亮模式/s的表格输出。