$ 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
默认情况下,
grep
返回包含搜索项的每一行:$ grep test test
test line 1
test line 2
test line 3 with two test words
test line 4
将
--color
参数传递给grep
将使其突出显示与搜索表达式匹配的行部分,但仍仅返回包含该表达式的行。有没有办法让grep
输出源文件中的每一行,但突出显示匹配项?没有匹配项)是:$ grep -B 9999 -A 9999 test test
如果
grep
无法完成此操作,是否还有另一个命令行工具可以提供相同的功能?我弄弄过ack
,但似乎也没有选择。#1 楼
grep --color -E "test|$" yourfile
我们在这里所做的与
$
模式和测试模式相匹配,显然$
没有任何要着色的颜色,因此只有测试模式才会变色。 -E
只是打开扩展的正则表达式匹配。您可以像这样轻松地创建函数:
highlight () { grep --color -E "|$" "${@:1}" ; }
评论
真是太厉害了!
– gvkv
2010年8月12日下午3:09
并作为一个函数:Highlight(){grep --color -E“ $ 1 | $” $ 2; }。用法:突出显示测试您的文件
– Stefan Lasiewski
2010-10-14 3:48
更好的方法是:Highlight(){grep --color -E“ $ 1 | $”“ $ @”}允许文件名中带有空格的文件和多个文件。
–迈克·德西蒙(Mike DeSimone)
2011年7月24日在5:34
@MikeDeSimone-但是文件中也将包含“ $ 1”。使用高亮(){grep --color -E“ $ 1 | $”“ $ {@:1}”}
–克里斯唐(Chris Down)
11年11月17日在11:48
我用bash想到了这个$ {@:2},因为您不希望在列表文件中重复第一个参数来检查。 Highlight(){grep --color -E-“ $ 1 | \ $”“ $ {@:2}” ;; }。注意-也表示用破折号表示参数已完成,因此,如果您搜索模式行-则该行仍然有效。
–林奇
16-3-13在5:08
#2 楼
ack --passthru --color string file
对于Ubuntu和Debian,使用ack-grep代替ack
ack-grep --passthru --color string file
评论
哦,这在手册页中很明显;我瞎了。谢谢
– Michael Mrozek
2010年8月17日在20:03
grap的模式可以用--regexp字符串显式指定; ack / ack-grep等效项是--match字符串
–大黄
15年1月8日在17:46
用perl模拟ack --passthru:grep_passthrough(){! perl -ne“打印; \ $ e || = / $ @ /; END {{exit \ $ e}}”; }
–卢卡斯·西蒙(Lucas Cimon)
16 Mar 4 '16 at 17:58
ack --passthru也可以在流上使用!例如,ifconfig | ack --passthru inet
– honkaboy
16年6月16日,0:10
#3 楼
使用grep
正确且可移植的另一种方法(除了使用两个正则表达式交替使用,如公认的答案一样)是通过null模式(以及分别为null字符串)。因为,按照标准:-E
Match using extended regular expressions.
[...] A null ERE shall match every line.
和
-F
Match using fixed strings.
[...] A null string shall match every line.
所以这只是运行问题/>
grep -E -e '' -e 'pattern' infile
和
grep -F -e '' -e 'string' infile
评论
或者只是grep -F -e''-e'string'。
–StéphaneChazelas
17年1月26日在23:14
它适用于GNU grep 2.25,busybox grep和传家宝工具。
–StéphaneChazelas
17年1月26日在23:25
好吧,我不好,seq 3 | grep -F -e''-e 2仅在2.27中输出2(和2.26,但不输出2.25,并且不在git头中)。仅带有-F(不带有-E或不带有)。 IOW,只有2.26和2.27似乎有此错误,并且只有-F。
–StéphaneChazelas
17年1月26日23:56
注意seq 3 | grep -F -e''-e''-e 2似乎在2.27上也能正常工作
–StéphaneChazelas
17年1月27日,0:03
此答案中给出的方法简单,正确,并且看起来非常快。就像您说的那样,它与-F自动配合使用,从而无需担心字符串中会出现什么字符。您可能要提到--color;由于此答案在页面上浮动(通过投票查看时),因此更多的人可能最终会在其他答案之前阅读它。
– Eliah Kagan
17年1月27日在5:12
#4 楼
我具有用于此类用途的以下功能:highlight () {
perl -pe "s//\e[1;31;43m$&\e[0m/g"
}
内部看起来很丑陋,它很好用且易于使用,就像这样:
cat some_file.txt | highlight some_word
,或者,例如,更真实一些的示例: (使用grep可能很难-我不确定)将
1
和31
和43
(在\e[
之后)更改为不同的值。到处都有使用的代码,但这是一个快速的介绍:1粗体显示文本,31
使其变为红色,而43
给出黄色背景。 32
或33
将使用不同的颜色,44
或45
将使用不同的背景:您明白了。如果您愿意,甚至可以使其闪烁(使用5
。)这不使用任何特殊的Perl模块,Perl几乎无处不在,所以我希望它可以正常工作大约在任何地方。 grep解决方案非常聪明,但是grep上的--color开关并非在所有地方都可用。例如,我只是在运行bash,运行ksh的Solaris盒和运行zsh的本地Mac OS X机器上尝试了此解决方案。一切都很好。但是,Solaris使grep --color
解决方案感到窒息。我工作的许多服务器。 (我忘记了为什么:我认为它与所需的Perl模块有关。)嵌入式系统,Linksys路由器等),我想说这是一个通用的解决方案。评论
我喜欢此解决方案,因为它可以满足您的需求,而不是像grep这样的弯曲工具和更间接的现有工具。如果您要更改行为,它还为您提供了更大的灵活性。 (尽管只是一个注释,您可以使用带有相同SGR代码的env var GREP_COLORS使用grep更改颜色)。
–wardw
20/12/17在16:16
还需要注意的是,匹配后颜色将用\ e [0m重置,因此这还将清除输入流中所有现有的颜色。但是,grep也是如此。如果需要处理已着色的输入,则可以考虑使用终端控件tput smso和tput rmso来包装匹配文本。
–wardw
20 Dec 17 '20 at 16:20
#5 楼
代替使用Grep,可以使用Less:less file
像这样搜索:
/pattern
输入这将:
滚动到第一条匹配行
从那里开始输出每行
突出显示所有匹配项
滚动到下一条匹配行:
n
滚动到上一个匹配行:
N
切换突出显示:Esc
u
如果您愿意,也可以更改突出显示颜色。
#6 楼
ripgrep
将
ripgrep
与--passthru
参数一起使用:rg --passthru pattern file.txt
它是最快的grepping工具之一,因为它是基于Rust的正则表达式引擎构建的,该引擎使用有限自动机,SIMD和积极的文字优化来进行搜索非常快。
--passthru
-同时打印匹配和不匹配的行。实现类似效果的另一种方法是修改模式以匹配空字符串。例如,如果您使用
rg foo
搜索,则使用rg "^|foo"
代替,它将在搜索到的每个文件中发出每一行,但仅高亮显示foo。此标志启用相同的行为,而无需修改模式。#7 楼
您可以尝试:perl -MTERM::ANSIColor -nle '/pattern/ ? print colored($_, 'color') : print' test
但是,它不是很便携,即使安装了Perl,也可能需要下载另一个模块。此外,它将为整行着色,而不仅仅是搜索词。
#8 楼
到目前为止,没有给出的答案都提供了便携式解决方案。perl
,ack
,ggrep
,gsed
,bash
之类,但仅需要POSIX shell和POSIX强制实用程序sed
和printf
:grepc()
{
pattern=
shift
esc=$(printf "3")
sed 's"'"$pattern"'"'$esc'[32m&'$esc'[0m"g' "$@"
}
:
grepc string_to_search [file ...]
可以通过在sed命令参数中使用以下代码之一来调整突出显示颜色(此处32m为绿色):
30m black
31m red
33m yellow
34m blue
35m magenta
36m cyan
37m white
7m reverse video
1只要您的终端支持ANSI颜色转义序列。
#9 楼
对于GNU grep,有一种更简便的方法,但我认为它不是可移植的(即BSD grep):在管道中: >
在文件上:
cat <file> | grep --color=always -z <query>
贷方在此处输入Cyrus的答案。
评论
这不是您(和Cyrus)所想的答案。它具有将整个文件视为一行的效果。因此,(1)如果文件很大,则可能会出现内存不足的情况;(2)如果文件根本不包含模式,则将不会输出任何内容。而且你是对的;它不是普遍可用的。 (但是再说一遍,--color也不是标准的。)
– G-Man说“恢复莫妮卡”
17年2月6日在4:43
支持什么版本的grep?在grep 2.5.4上,-z似乎不可用...
– Alex
17年6月29日在22:29
#10 楼
一个sed
版本,可同时在
bash
和ash
上使用。#11 楼
OP要求grep
,这是我建议的内容;但经过努力解决sed
的问题后,记录下来,这是一个简单的解决方案:sed $'s/main/\E[31m&\E[0m/g' testt.c
将
main
涂成红色。 br /> \E[31m
:匹配的模式\E[0m
:一行中的所有单词,不仅是第一个单词&
是带有解释为转义字符的bash字符串/> 关于grep,它也可以使用
/g
(行首)而不是$'string'
(行尾)来工作。例如:cat testt.c | sed $'s/main/\E[31m&\E[0m/g'
为了显示这个我不推荐的疯狂别名,您甚至可以使用开放引号: br />
所有工作! :)如果您忘记关闭引号,请不要担心,bash会以“连续行字符”记住您。
#12 楼
如果您对grep
的返回值感兴趣,那么GNU sed
也是这样:sed '/pattern/h; ${p;x;/./Q0;Q1}'
您可以在脚本行中添加修改,例如:
sed '/pattern/h; ${p;x;/./Q0;Q1}; s/pattern/<pattern
>/g'
这将检查
$
是否出现在当前行上,并将其存储在保持缓冲区中。在文件末尾(p
),打印最后一行(x
),然后交换保留空间和模式空间(/./
)。接下来,测试模式空间是否为空(0
),如果它是非空的,则以代码q4312079q(Q0
)退出,否则以代码1(Q1
)退出。另一种方法是
/pattern/{:a $q1; n; ba}
,在检测到pattern
后循环更改当前行可能会很棘手。
评论
可能的跨站点重复项:stackoverflow.com/questions/981601/…两者的最高答案是相同的。您可以使用-C 9999代替-A 9999 -B 9999.我总是这样做:grep -C 9999模式文件
尝试sed。例如,以下是突出显示+返回退出代码的方法:askubuntu.com/a/1200851/670392