当输入段落不是单行时,为搜索结果着色

时间:2017-03-03 08:08:43

标签: bash perl awk grep

我正在尝试使用突出显示的搜索字符串打印整个文件的内容。

对于Record等于单行的简单文件,我可以使用以下方法轻松完成:

grep --color=auto "myseacrchpattern" inputfile

这里我的记录是段落形式而不是单行。例如:

CREATE TABLE mytable ( id SERIAL,
name varchar(20),
cost int );

CREATE TABLE notmytable ( id SERIAL,
name varchar(20),
cost int );

如果我使用grep作为关键字:" notmytable",它会给我彩色输出,但只打印该行。

grep --color=auto 'notmytable' inputfile
CREATE TABLE notmytable ( id SERIAL,  # <-- "notmytable" is in red but its not the whole query

我需要这样的东西:

CREATE TABLE notmytable ( id SERIAL,   # <---"notmytable" is in red
name varchar(20),
cost int ); 

我可以用awk或perl打印所需的段落但是如何着色它:

awk -v RS=';' -v ORS=';\n' '/notmytable/' inputfile


CREATE TABLE notmytable ( id SERIAL,
name varchar(20),
cost int );

OR perl:

perl -00lne 'print $_ if /notmytable/' inputfile
CREATE TABLE notmytable ( id SERIAL,
name varchar(20),
cost int );

3 个答案:

答案 0 :(得分:4)

perl "-MTerm::ANSIColor qw(:constants)" -00lnE'
    next if not /notmytable/; 
    for (split "\n") { /notmytable/ ? say RED $_, RESET : say }
' input

:constants代码提供RED等。还有其他方法,请参阅Term::ANSIColor

请注意,必须有一些重复的搜索,因为我们需要首先识别段落,但是在正常打印其他行时才打印该行。

如果只需要对图案进行着色,则不需要双重解析(并且它更容易和更好)

perl -MTerm::ANSIColor -00lnE'say if s/(notmytable)/colored($1,"red")/eg' input

答案 1 :(得分:2)

如果找到与所需正则表达式匹配的字符串,则用适当的字符将其包围以更改其颜色并打印包含它的记录:

$ awk -v RS=';' -v ORS=';\n' 'gsub(/notmytable/,"<RED>&</RED>")' file
CREATE TABLE <RED>notmytable</RED> ( id SERIAL,
name varchar(20),
cost int );

只需将<RED></RED>更改为该颜色的转义序列,例如

awk -v RS=';' -v ORS=';\n' 'gsub(/notmytable/,"\033[31m&\033[0m")' file

或者如果您不想对这些颜色值进行硬编码,您可以这样做:

awk -v RS=';' -v ORS=';\n' -v red="$(tput setaf 1)" -v nrm="$(tput sgr0)" 'gsub(/notmytable/,red"&"nrm)' file

顺便说一句,如果您使用-v RS= -v ORS='\n\n'找到的所有记录之间的空白行比-v RS=';' -v ORS=';\n'更适合您。

答案 2 :(得分:1)

将您的awkperl解决方案与grep

结合使用
perl -00lne 'print $_ if /notmytable/' input|grep -C1000 notmytable

-C1000选项会使grep在匹配行周围保留1000行周围环境,实际上将grep转换为仅仅着色器而不是行选择器。

您可以将其包装成bash函数:

function paragrep() { perl -00lne 'print $_ if /'"$1"/ "$2"|grep -C1000 "$1"; }

用法示例:

$ paragrep notmytable input
CREATE TABLE notmytable ( id SERIAL,    # <---"notmytable" is in red
name varchar(20),
cost int );

$