在一个复杂的脚本中,我使用grep
模式文件来获取匹配的行
例如:这是包含文本的文件
$ cat file.txt
abc$(SEQ)asdasd
wwww$(SEQ)asqqqqqq
efg hij$(SEQ)asdasdasd$(SEQ)zzzzzz
klmn$(SEQ)11111111
op$(SEQ)44444444
qrs$(SEQ)777
tuv$(SEQ)mmmmmmmmm
qrs$(SEQ)777444
asdsd777hdhfgjdfasd
wxyzfhdfghdfh
这是模式文件
$ cat pattren.txt
444
777
asd
我正在使用以下grep
命令来获取匹配的行
在命令行中,我可以看到匹配的模式,但在日志中却看不到。所以我需要一种方法来打印匹配的行和匹配的模式。输出应该类似于:在 TAB 键(或任何可识别的格式)后打印模式。
abc$(SEQ)asdasd <TAB> asd
efg hij$(SEQ)asdasdasd$(SEQ)zzzzzz <TAB> asd
op$(SEQ)44444444 <TAB> 444
qrs$(SEQ)777 <TAB> 444
qrs$(SEQ)777444 <TAB> 777444
asdsd777hdhfgjdfasd <TAB> asd777
我可以使用 grep-o
但无法将两者(即有和无-o
)结合在一起。
没有必要使用grep
,我很乐意使用任何其他可以完成此操作的命令。
一个
awk
想法:或者,将脚本主体放在
awk
文件中,然后通过以下方式访问awk -f ...
:笔记:
patterns.txt
没有任何前导/尾随空格,否则会导致调用index()
失败(ptn in ptns)
不保证模式的处理顺序,这意味着无法保证在行尾打印时所述模式的顺序;虽然可以添加额外的代码来满足排序要求,但 OP 需要提供更多细节以包括如何处理重复和/或重叠的模式(例如,a
并且as
会在同一index()
位置匹配,因此哪种模式会被视为实际匹配?)index()
只会找到模式的第一次出现,并且我们不会尝试匹配第一个匹配之后的匹配,所以这种方法只会告诉我们至少有一个4
匹配;需要额外的编码来确定匹配的数量,但也需要 OP 提供有关如何处理重复和/或重叠模式的更多详细信息(例如,与44
匹配多少次44444444
?)两种方法都会产生:
由于允许任何可识别的格式,最简单的解决方案是将 grep 发出的 ANSI 序列直接替换为您想要的任何分隔符,例如制表符:
也可以捕获开始和结束 ANSI 序列之间的每个匹配,例如这里我将每个匹配包装在
[]
要在最后打印图案,你可以使用类似这样的方法
如果你想保留颜色以供以后使用,你也可以直接这样做
要在 Perl 中执行此操作,请使用以下命令:
输出:
Perl“单行命令”使用以下命令行标志::
-e
告诉 Perl 在行内查找代码,而不是在文件中。-n
:一次循环输入一行,$_
默认情况下将其分配给。 :在行内执行代码之前-l
去除输入行分隔符(默认情况下在 *NIX 上),并在打印时附加它。"\n"
正则表达式使用这个修饰符::
g
重复匹配模式。上面这一行将文件内容读
pattern.txt
入数组@pats
并删除换行符(chomp
)。$pat = join "|", @pats;
:将模式连接成一个字符串,用|
(= OR运算符)分隔。@matches = m{($pat)}g
:将模式重复匹配(m{...}g
)从 读取的当前行file.txt
。所有匹配都存储在数组中@matches
(如果出现多次,则可能包含相同模式的重复)。if ( @matches = ... )
:如果至少有一个匹配项,@matches
则评估为。 :使匹配项唯一并将其存储在数组中。:用逗号连接唯一匹配项,并将结果存储在一个字符串中。TRUE
@uniq = grep !$seen{$_}++, @matches;
@uniq
$uniq = join ",", @uniq;
$uniq
参见:
perldoc perlrun
:如何执行 Perl 解释器:命令行开关perldoc perlre
:Perl 正则表达式(regexes)perldoc perlrequick
:Perl 正则表达式快速入门