如何将grep与正则表达式和文件中的模式一起使用?

时间:2018-09-28 09:13:19

标签: regex linux grep

假设有一个文件包含很多模式

.com
.re
.net
...

并且有一个包含大量数据的文件

www.recent
www.remix3d.com
www.verisign.net

我想要的结果是

www.remix3d.com
www.verisign.net

我使用命令grep -f pattern_file data_file,但结果是这样

www.recent
www.remix3d.com
www.verisign.net

由于.rewww'.re'cent匹配

如何指定文件中的模式可以与常规正则表达式一起使用?例如我grep数据以特定模式“结尾”,而这些模式来自模式文件。

5 个答案:

答案 0 :(得分:0)

特征码文件必须包含特征码(即带有正确转义的特殊字符),我建议像这样修改您的特征码文件:

\.com$
\.ru$
\.net$

答案 1 :(得分:0)

如果您不想更改特征码文件,则必须从外部进行转义。检查一下。

> cat pattern
.com
.re
.net
> cat pattern_data
www.recent
www.remix3d.com
www.verisign.net
> grep $(sed 's/$/$/g;s/^/\\/g' pattern | tr '\n' '|' | sed 's/.$//g;s/|/\\|/g') pattern_data
www.remix3d.com
www.verisign.net
>

答案 2 :(得分:0)

请注意,已有一些用于域名匹配的工具,用于处理public suffix list。有许多libraries可用于处理它,其中一些经过了优化,如果后缀列表很大,它们将比处理正则表达式列表快得多。

答案 3 :(得分:0)

听起来您的标准实际上是:

  • 模式文件实际上是一个STRINGS列表,而不是正则表达式(其中一个点(.)与任何单个字符匹配的列表),
  • 这些模式只能在字符串的ENDS处进行匹配(因此,模式文件中每行的末尾都有一个隐式$)。

要满足第一个条件,可以使用grep的-F选项:

$ grep -F -f pattern_file data_file

但这对.re无效,它嵌入其中一行。如果可以修改病毒码文件,则将行更改为:

\.com$
\.re$
\.net$

会将它们转换为所需的正则表达式。否则,您可能必须使用某些东西来解析该模式文件,以创建所需的正则表达式。例如,使用bash数组和一些参数扩展:

$ mapfile -t a < pattern_file
$ declare -p a
declare -a a=([0]=".com" [1]=".re" [2]=".net")
$ printf -v new_re '|%s' "${a[@]}"
$ new_re="${new_re//./\\.}"         # escape dots within regex
$ new_re="(${new_re:1})\$"          # strip leading or-bar
$ echo "$new_re"
(\.com|\.re|\.net)$
$ grep -E "$new_re" data_file
www.remix3d.com
www.verisign.net

或者,如果您不介意使用另一种工具来减少行数,则:

$ grep -f <(sed 's/\./\\./g;s/$/$/' pat) file
www.remix3d.com
www.verisign.net

答案 4 :(得分:0)

您可以在流程替换中将grep -fsed一起使用,以将pattern_file中的每个扩展名转换为适当的正则表达式:

grep -f <(sed 's/.*/\\&$/' pattern_file) data_file

www.remix3d.com
www.verisign.net

sed命令的输出为:

sed 's/.*/\\&$/' pattern_file

\.com$
\.re$
\.net$