说服 grep 输出所有行,而不仅仅是那些匹配的行

Mic*_*zek 140 grep highlighting

假设我有以下文件:

$ cat test

test line 1
test line 2
line without the search word
another line without it
test line 3 with two test words
test line 4
Run Code Online (Sandbox Code Playgroud)

默认情况下,grep返回包含搜索词的每一行:

$ grep test test

test line 1
test line 2
test line 3 with two test words
test line 4
Run Code Online (Sandbox Code Playgroud)

传递--color参数 togrep将使其突出显示与搜索表达式匹配的行部分,但它仍然只返回包含该表达式的行。有没有办法grep输出源文件中的每一行,但突出显示匹配项?

我目前实现这一点的可怕黑客(至少在没有 10000+ 连续行且没有匹配项的文件上)是:

$ grep -B 9999 -A 9999 test test
Run Code Online (Sandbox Code Playgroud)

两个命令的截图

如果grep不能做到这一点,是否有另一个提供相同功能的命令行工具?我摆弄过ack,但它似乎也没有选择。

jac*_*onh 205

grep --color -E "test|$" yourfile
Run Code Online (Sandbox Code Playgroud)

我们在这里做的是匹配$图案和测试图案,显然$没有任何颜色,所以只有测试图案有颜色。在-E上扩展正则表达式匹配刚刚转。

您可以像这样轻松地从中创建一个函数:

highlight () { grep --color -E "$1|$" "${@:1}" ; }
Run Code Online (Sandbox Code Playgroud)

  • 这真是太棒了! (15认同)
  • @MikeDeSimone - 但文件中也会有“$1”。使用`highlight() { grep --color -E "$1|$" "${@:1}" }` (15认同)
  • 更好的可能是:`highlight () { grep --color -E "$1|$" "$@" }` 允许名称中包含空格的文件*和*多个文件。 (6认同)
  • 作为一个函数:`highlight () { grep --color -E "$1|$" $2 ; }`。用法:`highlight test yourfile` (3认同)
  • 我用 bash 想出了这个 `${@:2}`,因为你不希望在列表文件中重复第一个参数来检查。`highlight() { grep --color -E -- "$1|\$" "${@:2}"; }`。注意 `--` 也表示带破折号的参数已经完成,所以如果你搜索模式行 `-something` 它仍然有效。 (3认同)
  • @StefanLasiewski:也应该引用`"$2"`。 (2认同)

Den*_*son 42

ack --passthru --color string file
Run Code Online (Sandbox Code Playgroud)

对于 Ubuntu 和 Debian,使用 ack-grep 而不是 ack

ack-grep --passthru --color string file
Run Code Online (Sandbox Code Playgroud)

  • 哦,这在手册页中很明显;我瞎了。谢谢 (2认同)

don*_*sti 17

另一种方式来做到这一点正确便携grep(除了使用两个正则表达式与交替作为公认的答案)是通过空模式(分别为空字符串)。
它应该同样适用于-E-F开关,因为根据标准

-E
    Match using extended regular expressions. 
    [...] A null ERE shall match every line.
Run Code Online (Sandbox Code Playgroud)

-F
    Match using fixed strings.
    [...] A null string shall match every line.
Run Code Online (Sandbox Code Playgroud)

所以这只是一个跑步的问题

grep -E -e '' -e 'pattern' infile
Run Code Online (Sandbox Code Playgroud)

和分别

grep -F -e '' -e 'string' infile
Run Code Online (Sandbox Code Playgroud)


ico*_*ast 12

我有以下功能用于此类事情:

highlight () {
    perl -pe "s/$1/\e[1;31;43m$&\e[0m/g"
}
Run Code Online (Sandbox Code Playgroud)

它在内部看起来有点丑,但很好用,而且很容易使用,就像这样:

cat some_file.txt | highlight some_word
Run Code Online (Sandbox Code Playgroud)

或者,对于一个更真实的例子:

tail -f console.log | highlight ERROR
Run Code Online (Sandbox Code Playgroud)

您可以通过将1and3143(after \e[)更改为不同的值来将颜色更改为您喜欢的任何颜色(这对于 grep 来说可能很难——我不确定)。该代码到使用的是所有的地方,但这里有一个快速的介绍:1个加粗文本中,31它红色则使人和43给出了一个黄色的背景。 32或者33会是不同的颜色,44或者45会是不同的背景:你明白了。5如果你愿意,你甚至可以让它闪烁(用)。

这不使用任何特殊的 Perl 模块,而且 Perl几乎无处不在,所以我希望它几乎可以在任何地方工作。grep 解决方案非常聪明,但是 grep 上的 --color 开关并非随处可用。例如,我只是在运行 bash 的 Solaris 机器和另一个运行 ksh 的 Solaris 机器上以及运行 zsh 的本地 Mac OS X 机器上尝试了这个解决方案。一切都很好。grep --color然而,Solaris 对解决方案束手无策。

此外,ack 很棒,我向尚未发现它的任何人推荐它,但是我在我工作的许多服务器中的一些服务器上安装它时遇到了一些问题。(我忘了为什么:我认为与它需要的 Perl 模块有关。)

因为我认为我从来没有没有安装 Perl的 Unix 机器上工作过(嵌入式系统、Linksys 路由器等除外),所以我想说这几乎是一个普遍可用的解决方案.


ken*_*orb 7

ripgrep

ripgrep与其参数一起使用--passthru

rg --passthru pattern file.txt
Run Code Online (Sandbox Code Playgroud)

它是最快的 grep 工具之一,因为它建立在Rust 的正则表达式引擎之上,该引擎使用有限自动机、SIMD 和积极的文字优化来使搜索速度非常快。

--passthru- 打印匹配和不匹配的行。

实现类似效果的另一种方法是修改模式以匹配空字符串。例如,如果您正在使用 using 进行搜索,rg foo则 usingrg "^|foo"相反 将发出搜索到的每个文件中的每一行,但只会突出显示 foo 的出现。该标志无需修改模式即可实现相同的行为。