ChatGPT解决这个技术问题 Extra ChatGPT

Colorized grep -- 查看带有突出显示的匹配项的整个文件

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

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

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

如果您想要一种以上的颜色用于多种模式(即错误、警告、信息等消息),use sedsed 解决方案以增加复杂性为代价为您提供多种颜色(而不是大约 60 个字符,而不是大约 30 个字符)。
使用 sed,您甚至可以 highlight + return exit code,参见示例:askubuntu.com/a/1200851/670392
@TrevorBoydSmith:使用 sed,您可以在控制台终端上发送 beep 事件:stackoverflow.com/a/69266748/1765658

A
Abdull

以下是一些方法:

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

那个 |$ 技巧很巧妙!干得好,我一定要记住这一点。对于那些不精通正则表达式的人,“pattern|$”将匹配具有您正在搜索的模式的行和具有结尾的行 - 即所有这些行。因为行尾实际上不是任何字符,所以输出的彩色部分将只是您的模式。谢谢瑞恩!
您也可以省略“$”:egrep --color "pattern|" file(信用 stackoverflow.com/a/7398092/50979
@Zack,“|”运算符是 OR 运算符,而不是 AND,
@JBoy,我以传统的英语方式而不是布尔逻辑方式使用“AND”。你是对的,它确实是一个“或”运算符——它匹配这个和那个。 :P 很好的说明。
如果匹配多个模式,则似乎需要“$”。 egrep --color "pattern1|pattern2|$"。否则颜色高亮不会发生。
m
mit

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

less -p pattern file

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

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


也适用于使用 - 的管道(从 stding 读取):… | less -p pattern -
@phk:您甚至可以省略破折号。
此外,添加 -i 选项将使匹配不区分大小写,就像在 less -ip pattern file 中一样。
...如果管道在 ANSI 彩色输入中,请为 less 提供 -R 开关:… | less -Rip introduction -
e
ephemient

我想推荐ack -- better than grep, a power search tool for programmers

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


但是,有时,当我确定它一定存在时,它却找不到我想要的东西。 ack 很聪明,但有时过于聪明,它排除了命中所在的文件类型。
@MPi ack -a 将搜索所有文件类型,但仍排除 .git/ .svn/ 等。
但是,ack 不搜索我的图像,这很酷,所以 -a 做的太多了。我将 --type-set=freemarker=.ftl 添加到我的 ~/.ackrc 中,举个例子。
通过一些配置调整,grep 已经完成了 ack 所做的一切,而且速度更快,并且永远不会像 ack 的白名单有时那样忽略结果。也许将您喜欢的 grep 设置保存在 .bashrc 中。我的阅读: function grp() { GREP_OPTIONS="-rI --color --exclude-dir=\.git --exclude=tags" grep "$@"
t
tripleee

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

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

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

https://i.stack.imgur.com/XbB4X.png


该问题明确要求使用 grep 的解决方案,这是运行 *nix 的机器上的标准实用程序。
这个脚本很好,但不如另一个答案中提到的 colout 好。
@JonathanHartley 为什么会这样?我看不出有什么理由。此外,此脚本使用比 colout 简单得多的实现,如果您想检查它的作用,这很好。
@HelloGoodbye 是的,很公平。我应该推迟判决。 colout 更彻底、更强大,但你说得对,它的使用和逆向工程相应地更复杂。
@JonathanHartley 它更强大是有道理的!
F
Fabien Sa

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

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

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

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


如果您的系统上可用,您也可以只使用 egrep 。
将其结果管道化以减少颜色信息的丢失。你将如何防止这种情况发生?
@Hoten 使用 --color=always 而不是 --color
并且,要使 less 解释颜色代码,请使用 less -R
未引用 $2 的使用不是空白安全的。在 bash 我宁愿做 function grepe() { local pattern="$1" shift egrep --color "$pattern|^" "$@" } 对不起格式混乱。
J
Jonathan Hartley

使用 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

如其他地方所述,该问题明确要求使用 grep 的解决方案,这是运行 *nix 的机器上的标准实用程序。
@Zack 好的,对不起。实际上,如果您将问题扩展到 grep 之外,并且已经在答案中进行了扩展,那么 colout 是解决您遇到的问题的最佳解决方案,也是我所知道的最佳解决方案。根据 UNIX 哲学,应该编写程序来做好一件事。对于 grep,它正在过滤文本流。对于 colout,它正在着色或突出显示文本流。
这是最好的答案,因为它可以应用多种不同颜色的高光,而 colout 是一个非常有用的工具。学习一次,在许多情况下使用它,而不是学习一个工具来突出显示日志文件,另一个工具来突出显示测试输出等。
A
Abhishek Jaisingh

grep 的 -z 选项也很漂亮!

cat file1 | grep -z "pattern"

这是做什么的? -z 告诉 grep 使用 ASCII NUL 作为行分隔符...
@vy32 -z 基本上将整个文件转换为一行。但是,回复者假定 grep 还默认设置了“--color”选项,许多人在他们的 grep 别名中配置了该选项,但不是默认设置。
这就是我一直在寻找的答案。在管道中使用时效果很好。
警告: @rickgn,如果没有任何输入行有任何匹配,这 不会 传递任何内容。使用 echo "hello\nthere" | grep -z x 进行测试。
@alife 好点,它实际上有点酷,因为如果模式不在文本中,那么查看任何文本有什么意义?如果是长文本,则看不到输出可能比扫描输出以找出没有匹配项更快。 :)
d
dave1010

我使用来自 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
}

w
whoan

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

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

F
Faither

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

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

https://i.imgur.com/HmfeYOR.png


t
treulz

要在查看整个文件时突出显示模式,h 可以执行此操作。

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

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

您还可以将 h 的输出通过管道传输到 less -R 以便更好地阅读。

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


F
F. Hauri - Give Up GitHub

sed 方式

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

并且因为 sedgrep 更轻、更快,所以我更喜欢使用 sed 来完成这种工作:

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

这似乎不太直观。

\o33 是生成字符八进制 033 -> Escape 的 sed 语法。

ESC [ 47 ; 31; 1 m 是 ANSI 转义码:背景灰色、前景红色和粗体。

& 将重新打印图案

Esc [ 0 m 返回默认值。

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

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

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

使用 sed 的优势之一:您可以使用 bell ascii character 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= ...


W
Wernsey

这是一个 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


M
MarkHu

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

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

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

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


K
Kobunite

另一种肮脏的方式:

grep -A80 -B80 --color FIND_THIS IN_FILE

我做了一个

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

在 .bashrc 中。


如果您正在寻找的东西不存在,这将是有问题的。说由于错误,在这种情况下,您将一无所获。
A
Andrew Magee

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

ag <search> --passthrough

A
Al Mamun

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

grep -C 100 searchtext file

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


S
Serhii Nadolynskyi

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

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

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


B
Bruce Edge

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

rg --passthru...

颜色是默认值:

https://i.stack.imgur.com/XuUHy.png

  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

你永远不会回去。


谢谢,这有帮助。在依赖树中搜索现在更容易了。 rg --passthru 'setuptools' <(poetry show --tree)
由于我们允许通过向 grep 建议不同的选项来跑题,所以我可以向您介绍一下 ugrep,它在性能方面优于 ripgrep - 基本上所有其他方面 - 同时,添加很多额外的好东西。就我而言,由于 ugrep 包含 --replace 选项,我已经放弃了 sed 及其对正则表达式的古怪处理......而且,与标准 grep 不同,ugrep sed 快。
n
nik

好的,这是一种方法,

wc -l filename

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

grep -C NN --color=always filename

“-C 2147483647”如果你不想先 wc。在这里使用大量数字似乎不会减慢速度。
搜索字符串在哪里,如果没有预期的荧光笔匹配,这会输出任何内容吗?例如,echo "hello\nthere" | grep -C99 x 不产生任何结果。
E
Edoot

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

基本用法:

echo warn error debug info 10 nil | colog

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


d
dimo414

这里是 my approach,灵感来自 @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

D
Dr. Alex RE

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

如果没有显示所有上下文行的选项,选项 -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 工具是非常公平的。
M
MAPK

也试试:

egrep 'pattern1|pattern2' FILE.txt | less -Sp 'pattern1|pattern2'

这将为您提供带有突出显示模式的表格输出。