我发现 grep
的 --color=always
标志非常有用。但是,grep 只打印匹配的行(除非您要求上下文行)。鉴于它打印的每一行都有一个匹配项,突出显示并没有增加尽可能多的功能。
我真的很想cat
一个文件并查看突出显示模式匹配的整个文件。
有什么方法可以告诉 grep 打印正在读取的每一行,而不管是否匹配?我知道我可以编写一个脚本来在文件的每一行上运行 grep,但我很好奇这是否可以使用标准 grep
。
sed
。 sed
解决方案以增加复杂性为代价为您提供多种颜色(而不是大约 60 个字符,而不是大约 30 个字符)。
sed
,您可以在控制台终端上发送 beep 事件:stackoverflow.com/a/69266748/1765658
以下是一些方法:
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
这是相同的事情。很有可能,无论如何你会使用更少,所以试试这个:
less -p pattern file
它将突出显示模式并跳转到文件中第一次出现的模式。
您可以使用 n
跳转到下一个事件,使用 p
跳转到上一个事件。使用 q
退出。
-
的管道(从 stding 读取):… | less -p pattern -
-i
选项将使匹配不区分大小写,就像在 less -ip pattern file
中一样。
less
提供 -R
开关:… | less -Rip introduction -
我想推荐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
很聪明,但有时过于聪明,它排除了命中所在的文件类型。
ack -a
将搜索所有文件类型,但仍排除 .git/
.svn/
等。
ack
不搜索我的图像,这很酷,所以 -a
做的太多了。我将 --type-set=freemarker=.ftl
添加到我的 ~/.ackrc
中,举个例子。
您可以使用来自 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
好。
colout
简单得多的实现,如果您想检查它的作用,这很好。
您还可以创建别名。在您的 .bashrc (或 osx 上的 .bash_profile )中添加此功能
function grepe {
grep --color -E "$1|$" $2
}
您现在可以像这样使用别名:“ifconfig | grepe inet
”或“grepe css index.html
”。
(PS:不要忘记 source ~/.bashrc
在当前会话中重新加载 bashrc)
--color=always
而不是 --color
less
解释颜色代码,请使用 less -R
。
使用 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
之外,并且已经在答案中进行了扩展,那么 colout
是解决您遇到的问题的最佳解决方案,也是我所知道的最佳解决方案。根据 UNIX 哲学,应该编写程序来做好一件事。对于 grep
,它正在过滤文本流。对于 colout
,它正在着色或突出显示文本流。
colout
是一个非常有用的工具。学习一次,在许多情况下使用它,而不是学习一个工具来突出显示日志文件,另一个工具来突出显示测试输出等。
grep 的 -z
选项也很漂亮!
cat file1 | grep -z "pattern"
echo "hello\nthere" | grep -z x
进行测试。
我使用来自 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
}
我将此添加到我的 .bash_aliases 中:
highlight() {
grep --color -E "$1|\$"
}
正如已经建议的 grep -E '|pattern'
一样,只是想澄清一下也可以突出显示整行。
例如,tail -f somelog | grep --color -E '| \[2\].*'
(特别是 -E '|
部分):
https://i.imgur.com/HmfeYOR.png
sed 方式
由于已经有很多不同的解决方案,但没有一个将 sed
显示为解决方案,
并且因为 sed
比 grep
更轻、更快,所以我更喜欢使用 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=
...
这是一个 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”
另一个答案提到了 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”'
另一种肮脏的方式:
grep -A80 -B80 --color FIND_THIS IN_FILE
我做了一个
alias grepa='grep -A80 -B80 --color'
在 .bashrc 中。
我出于类似目的使用以下命令:
grep -C 100 searchtext file
这将说 grep 在突出显示的搜索文本之前和之后打印 100 * 2 行上下文。
它可能看起来像一个肮脏的黑客。
grep "^\|highlight1\|highlight2\|highlight3" filename
这意味着 - 匹配行的开头 (^) 或 highlight1 或 highlight2 或 highlight3。结果,您将突出显示所有 highlight* 模式匹配,即使在同一行中也是如此。
使用 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
快。
好的,这是一种方法,
wc -l filename
会给你行数——比如NN,然后你可以
grep -C NN --color=always filename
echo "hello\nthere" | grep -C99 x
不产生任何结果。
如果您想用不同颜色突出显示多个模式,请参阅 this bash 脚本。
基本用法:
echo warn error debug info 10 nil | colog
您可以在运行的同时按一个键然后输入键来更改图案和颜色。
这里是 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
有什么方法可以告诉 grep 打印正在读取的每一行,而不管是否匹配?
如果没有显示所有上下文行的选项,选项 -C999
将起到作用。大多数其他 grep 变体也支持这一点。但是:1) 没有找到匹配项时不产生输出;2) 此选项对 grep 的效率有负面影响:当 -C
值很大时,可能必须将这么多行临时存储在内存中,以便 grep 确定哪个匹配发生时显示的上下文行。请注意,grep 实现不加载输入文件,而是读取几行或在输入上使用滑动窗口。上下文的“之前部分”必须保存在窗口(内存)中,以便稍后在找到匹配项时输出“之前”上下文行。
^|PATTERN
或 PATTERN|$
之类的模式或与此相关的任何空匹配子模式(例如 [^ -~]?|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 ...
也试试:
egrep 'pattern1|pattern2' FILE.txt | less -Sp 'pattern1|pattern2'
这将为您提供带有突出显示模式的表格输出。
不定期副业成功案例分享
egrep --color "pattern|" file
(信用 stackoverflow.com/a/7398092/50979)egrep --color "pattern1|pattern2|$"
。否则颜色高亮不会发生。