突出显示类似于 grep 的文本,但不过滤掉文本 [重复]

Posted

技术标签:

【中文标题】突出显示类似于 grep 的文本,但不过滤掉文本 [重复]【英文标题】:Highlight text similar to grep, but don't filter out text [duplicate] 【发布时间】:2011-11-15 16:08:48 【问题描述】:

使用 grep 时,它会突出显示与您的正则表达式匹配的行中的任何文本。

如果我想要这种行为,但也让 grep 打印出所有行怎么办?快速浏览了 grep 手册页后,我发现空空如也。

【问题讨论】:

咩? grep 我知道只是输出匹配的行。您所说的突出显示是什么? 作为一个快速的解决方案,使用 -A 和 -B,将其设置为足够高的值,您将看到所有行。正确的解决方案是可能使用 sed/perl/awk 等,仅在匹配的单词周围添加颜色转义码 @TomZych 不确定你是不是认真的,但有些发行版默认没有启用颜色。试试 --color 选项 【参考方案1】:

使用确认。在此处查看其--passthru 选项:ack。它具有允许完整的 perl 正则表达式的额外好处。

$ ack --passthru 'pattern1' file_name

$ command_here | ack --passthru 'pattern1'

你也可以像这样使用 grep:

$ grep --color -E '^|pattern1|pattern2' file_name

$ command_here | grep --color -E '^|pattern1|pattern2'

这将匹配所有行并突出显示模式。 ^ 匹配每行的开头,但不会被打印/突出显示,因为它不是字符。

(请注意,大多数设置将默认使用 --color。您可能不需要该标志)。

【讨论】:

这不适用于所有风格的 grep。一些greps 优化了模式以获得最快的匹配。 Mac OS X Mountain Lion 切换到了 BSD 风格的 grep,这对它不起作用。优化后的表达式匹配所有行,但没有突出显示。 至于@willkil,grep 版本不适合我。这里唯一的解决方案是 ack 方法。 以下对我有用:grep --color -E '(^|pattern1|pattern2)' file name。在某些 grep + 其他正则表达式的风格中,对模式进行 OR 匹配,它需要在括号内。 我之前的评论让我想到尝试grep --color -E '888|999|$':它有效!区别必须在于使用text- vs regex-directed 正则表达式引擎。 使用 OSX grep,grep --color -E 'pattern1|$' 有效【参考方案2】:

您可以确保所有行都匹配,但在不相关的匹配上没有要突出显示的内容

egrep --color 'apple|' test.txt 

注意事项:

egrep 也可以拼写为 grep -E --color 通常是大多数发行版中的默认值 grep 的某些变体会“优化”空匹配,因此您可能希望使用“apple|$”来代替(请参阅:https://***.com/a/13979036/939457)

【讨论】:

太棒了。所有的魔法都在管道字符中。非常感谢! 就像@holygeek 的回答一样,这并不适用于所有greps。所有行都匹配,但没有突出显示。 那里不需要-i(不区分大小写的匹配项)。此外,--color 是大多数设置中的默认设置,您可能不需要它。 grep -Eegrep 一样工作。它也适用于像ls | egrep 'pattern|'. The pipe can go after or before any pattern |pattern' 这样的命令输出。您可以使用一组模式添加更多管道pattarn1|pattern2|【参考方案3】:

编辑:

这适用于 OS X Mountain Lion 的 grep:

grep --color -E 'pattern1|pattern2|$'

这比'^|pattern1|pattern2' 好,因为替换的^ 部分匹配行首,而$ 匹配行尾。一些regular expression engines 不会突出显示pattern1pattern2,因为^ 已经匹配并且引擎渴望

'pattern1|pattern2|' 会发生类似的情况,因为正则表达式引擎注意到模式字符串末尾的空替换与主题字符串的开头匹配。

[1]: http://www.regular-expressions.info/engine.html

第一次编辑:

我最终使用了 perl:

perl -pe 's:pattern:\033[31;1m$&\033[30;0m:g'

这假设您有一个兼容 ANSI 的终端。

原始答案:

如果您遇到一个奇怪的grep,这可能会起作用:

grep -E --color=always -A500 -B500 'pattern1|pattern2' | grep -v '^--'

调整数字以获得所需的所有行。

第二个grep 只是删除了在Mac OS X Mountain Lion 上由BSD 样式grep 插入的无关-- 行,即使连续匹配的上下文重叠。

我以为 GNU grep 在上下文重叠时省略了 -- 行,但已经有一段时间了,所以也许我记错了。

【讨论】:

@sorin:是的,但问题还在于在打印所有行时突出显示匹配行,这对于所有greps 来说都是不可能的。特别是,所选答案和您的答案 在 OSX Mountain Lion 上不起作用 +1 这不值得反对,至少它可以在 OSX 10.7 上运行^ 在 Big Sur 上使用两种模式(虽然不是三种)grep --color -E '$|master|main|$' @rtc11 奇怪。我对 Big Sur 11.3.1 上的三个、四个、五个替补没有问题。你的例子看起来不错。 ¯\_(ツ)_/¯【参考方案4】:

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

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

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

【讨论】:

这似乎很有帮助,但即使在更改了顶部的 shebang 之后,它也无法在我的 debian 盒子上工作 =( 我需要的不仅仅是 highlight.sh 吗? 效果很好!爱它。值得一提的是,最好将脚本包含在您的 ~/.bashrc 中,并删除“函数”一词。这样它就可以作为 shell 的一个函数。 这也是一个完美的功能,例如我的 .zshrc【参考方案5】:

由于您希望突出显示匹配项,这可能是供人使用的(而不是例如管道到另一个程序),因此一个不错的解决方案是使用:

less -p <your-pattern> <your-file>

如果你不关心大小写:

less -i -p <your-pattern> <your-file>

这也有页面的优点,这在必须通过长输出时很好

【讨论】:

dosomestuff | less -p 'thingIwant'【参考方案6】:

您可以通过以下方式仅使用 grep 来完成:

    逐行读取文件 匹配每行中的模式并通过 grep 突出显示模式 如果没有匹配,则按原样回显该行

它为您提供以下内容:

while read line ; do (echo $line | grep PATTERN) || echo $line  ; done < inputfile

【讨论】:

【参考方案7】:

如果你想打印“所有”行,有一个简单的工作解决方案:

grep "test" -A 9999999 -B 9999999
A => 之后 B => 之前

【讨论】:

这样,每次 grep 匹配时文件都会完全回显,这很可能不是您想要的。 @sjas 呃,这不正是 OP 想要的吗? @Kyle Strand,OP 希望能够打印整个文件;使用此解决方案,如果给定文件有十个“测试”匹配项,则此解决方案将打印该文件十次,这可能不是 OP 想要的。 @user993865 你测试了吗?事实并非如此。 (即,grep 确实不会多次打印任何行。) 如果根本没有匹配项,这将不起作用【参考方案8】:

如果您这样做是因为您想在搜索中获得更多上下文,您可以这样做:

cat BIG_FILE.txt | less

less 中进行搜索应该会突出显示您的搜索词。

或者将输出通过管道传输到您最喜欢的编辑器。 One example:

cat BIG_FILE.txt | vim -

然后搜索/突出显示/替换。

【讨论】:

【参考方案9】:

如果您正在递归查找目录中的模式,您可以先将其保存到文件中。

ls -1R ./ | list-of-files.txt

然后用 grep 搜索,或通过管道将其发送到 grep 搜索

ls -1R | grep --color -rE '[A-Z]|'

这将列出所有文件,但用大写字母着色。如果删除最后一个 |您只会看到匹配项。

例如,我使用它来查找名称错误且大写的图像,但普通的 grep 不会在每个目录中仅显示每个文件的路径,因此我可以通过这种方式查看上下文。

【讨论】:

据我所知,唯一真正回答问题的部分是模式结束管道字符,当您发布此问题时,它已经在至少两个其他答案中得到了证明。 【参考方案10】:

也许这是一个XY problem,而您真正想做的是突出显示出现在您的外壳中的单词。如果是这样,您也许可以为此使用终端仿真器。例如,在 Konsole 中,启动 Find (ctrl+shift+F) 并输入您的单词。然后,只要它出现在新的或现有的输出中,就会突出显示该单词,直到您取消该功能。

【讨论】:

即使突出显示出现的单词是“真正的”需要,这也不是通用的解决方案。即使是 GNOME 终端(一个同样丰富的仿真器)的查找功能也不会出现这种行为(将焦点移回提示符会立即取消突出显示搜索模式)。无论如何,我不相信这是一个 XY 问题。

以上是关于突出显示类似于 grep 的文本,但不过滤掉文本 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

选择元素中的文本(类似于用鼠标突出显示)

选择元素中的文本(类似于用鼠标突出显示)

正则和grep——再做正则就去死

21.egrep进阶及文本处理工具应用

如何禁用文本选择突出显示

创建能够对突出显示的文本进行操作的应用程序扩展