601

我发现grep's --color=alwaysflag 非常有用。但是,grep 只打印匹配的行(除非您要求上下文行)。鉴于它打印的每一行都有一个匹配项,突出显示并没有增加尽可能多的功能。

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

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

4

23 回答 23

946

以下是一些方法:

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

|符号是 OR 运算符。要么使用转义它,\要么告诉 grep 搜索文本必须通过添加 -E 或使用egrep命令而不是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
于 2009-06-11T15:30:58.197 回答
110

这是相同的事情。很有可能,无论如何你会使用更少,所以试试这个:

less -p pattern file

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

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

于 2009-06-11T22:53:21.393 回答
50

我想推荐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)),并且在搜索许多文件时具有更好的上下文显示。

于 2009-06-17T18:05:04.927 回答
28

您可以从https://github.com/kepkin/dev-shell-essentials使用我的highlight脚本

比因为您可以用自己的颜色grep突出显示每个匹配项要好。

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

Github 项目的屏幕截图

于 2014-08-18T07:03:31.183 回答
21

您还可以创建别名。在您的 .bashrc (或 osx 上的 .bash_profile )中添加此功能

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

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

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

于 2014-04-30T13:13:07.783 回答
19

使用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
于 2015-06-19T10:47:43.597 回答
17

grep的-z选项也很漂亮!

cat file1 | grep -z "pattern"
于 2019-02-20T19:35:13.507 回答
9

我使用来自 O'Reilly 的“Linux Server Hacks”的 rcg。它非常适合您想要的内容,并且可以突出显示多个表情,每个表情都具有不同的颜色。

#!/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
}
于 2009-06-29T06:08:10.597 回答
8

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

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

于 2020-10-25T16:40:08.270 回答
7

我将此添加到我的 .bash_aliases 中:

highlight() {
  grep --color -E "$1|\$"
}
于 2015-03-13T07:46:35.420 回答
3

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

此外,它对不同的图案使用不同的颜色。

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

您还可以通过管道输出htoless -R以便更好地阅读。

要为每个模式 grep 和使用 1 种颜色,cxpgrep可能是一个很好的选择。

于 2017-04-06T21:05:28.730 回答
1

这是一个 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中的一篇文章“ So You Like Color ”。

于 2009-06-11T15:38:03.843 回答
1

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

我最近发现ccze哪个是更强大的着色器。我唯一的抱怨是它是面向屏幕的(例如less,我从不使用它),除非您为“原始 ANSI”输出指定 -A 开关。

+1 为上述rcg提及。它仍然是我的最爱,因为在别名中自定义非常简单。这样的东西通常在我的 ~/.bashrc 中:

别名 tailc='tail -f /my/app/log/file | rcg 发送“BOLD GREEN”接收“CYAN”错误“RED”'

于 2012-04-11T22:20:20.257 回答
1

另一种肮脏的方式:

grep -A80 -B80 --color FIND_THIS IN_FILE

我做了一个

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

在 .bashrc 中。

于 2013-05-17T13:55:33.500 回答
1

或者,您可以使用The Silver Searcher并执行

ag <search> --passthrough
于 2016-06-07T01:55:58.910 回答
1

我出于类似目的使用以下命令:

grep -C 100 searchtext file

这将说 grep 在突出显示的搜索文本之前和之后打印 100 * 2 行上下文。

于 2018-10-17T07:36:47.373 回答
1

它可能看起来像一个肮脏的黑客。

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

这意味着 - 匹配行的开头 (^) 或 highlight1 或 highlight2 或 highlight3。结果,您将突出显示所有 highlight* 模式匹配,即使在同一行中也是如此。

于 2020-08-14T21:35:01.317 回答
1

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

rg --passthru...

颜色是默认值:

在此处输入图像描述

  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.

亵渎,当然,但 grep 已经自满了。

brew/apt/rpm/whatever install ripgrep

你永远不会回去。

于 2021-01-16T00:47:16.330 回答
1

方式_

由于已经有很多不同的解决方案,但没有一个显示sed为解决方案,

并且因为sed比 更轻更快grep,我更喜欢sed用于这种工作:

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

这似乎不太直观。

  • \o33sed生成字符的语法octal 033-> Escape
  • Esc [ 47 ; 31 ; 1 mANSI 转义码:背景灰色,前景红色和粗体。
  • &将重新打印图案
  • Esc [ 0 m返回默认值。

通过使用它,您可以突出显示整行,但标记图案是红色的:

sed <file -e \
    's/^\(.*\)\(234\)\(.*\)/\o33[47m\1\o33[31;1m\2\o33[0;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甚至from=在某些文件中搜索/var/log/mail.log...

于 2021-09-21T09:45:01.403 回答
0

好的,这是一种方法,

wc -l filename

会给你行数——比如NN,然后你可以

grep -C NN --color=always filename
于 2009-06-11T15:30:24.670 回答
0

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

基本用法:

echo warn error debug info 10 nil | colog

您可以在运行的同时按一个键然后输入键来更改图案和颜色。

于 2016-10-24T21:24:17.360 回答
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
于 2020-02-28T01:03:13.370 回答
0

有什么方法可以告诉 grep 打印正在读取的每一行,而不管是否匹配?

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

诸如^|PATTERNor之类的模式PATTERN|$或任何与此相关的空匹配子模式[^ -~]?|PATTERN是一个不错的技巧。但是,1) 这些模式不会显示突出显示为上下文的不匹配行,以及 2) 这不能与其他一些 grep 选项结合使用,-F例如-w

所以这些方法都没有让我满意。我正在使用ugrep和增强的 grep 选项-y,可以有效地将所有不匹配的输出显示为颜色突出显示的上下文行。其他类似 grep 的工具,例如 ag 和 ripgrep 也提供了传递选项。但是 ugrep 与 GNU/BSD grep 兼容,并提供了 grep 选项的超集,例如-y-Q。例如,以下是与(interactive query UI to enter patterns)-y结合使用时显示的选项:-Q

ugrep -Q -y FILE ...
于 2020-04-16T16:46:55.933 回答