假设有一个文件包含很多模式
.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
由于.re
与www'.re'cent
匹配
如何指定文件中的模式可以与常规正则表达式一起使用?例如我grep数据以特定模式“结尾”,而这些模式来自模式文件。
答案 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)
听起来您的标准实际上是:
.
)与任何单个字符匹配的列表),$
)。要满足第一个条件,可以使用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 -f
与sed
一起使用,以将pattern_file
中的每个扩展名转换为适当的正则表达式:
grep -f <(sed 's/.*/\\&$/' pattern_file) data_file
www.remix3d.com
www.verisign.net
sed
命令的输出为:
sed 's/.*/\\&$/' pattern_file
\.com$
\.re$
\.net$