file1.txt
我有一个包含以下数据的文件:
MIME_HTML_ONLY
SUSPICIOUS_RECIPS
SORTED_RECIPS
HFILTER_HELO_5
另一个文件file2.txt
的行如下:
HFILTER_FROM_BOUNCE FORGED_OUTLOOK_HTML
SORTED_RECIPS HFILTER_HELO_5
MIME_HTML_ONLY HFILTER_FROM_BOUNCE
SUSPICIOUS_RECIPS ANY_OTHER_WORD
:
:
我想找到谁的数据中的所有行file2.txt
(该行的所有单词)是中存在的数据的子集file1.txt
例如对于输出上面应该是这一行:
SORTED_RECIPS HFILTER_HELO_5
现在我可以循环并读取 的各个行file2.txt
,看看它是否是 的子集file1.txt
。但我必须为 1000 个不同的file1.txt's
.因此,循环遍历file2.txt
for every的各个行file1.txt
非常慢。有什么有效的方法可以使用 来做到这一点吗awk
sed
grep
?
答案1
awk 'FNR == NR && $0 !~ /^[[:blank:]]*$/ { Dict[$0] = 1 }
FNR != NR {
i = 1
while( i <= NF && Dict[ $i] == 1) i++
if( i > NF) print
}
' File1.txt File2.txt
- 通用,不依赖于 file2 每行的字段/字数
- 处理两个文件的已排序和未排序内容
- 使用内存加载第一个文件字典所以如果要验证大量单词,可能不是最好的
- 提供给 awk 的文件顺序是强制性的
- 第一个是字典参考
- 任何(至少 1)个其他都是要过滤的文件
概念:
- 使用值作为索引加载数组中的每个单词
- 取值1(未赋值默认为0)
- 来自第一个文件 [其中 FNR(文件记录号)= NR(自第一次打开文件以来的记录号),默认情况下,一条记录是 awk 中的一行]
- 空行上有一个过滤器(没有字符或只有空格)
- 初始化计数器 (i)
- 将每个字段(默认情况下由于空格分隔符而导致此处的单词)与字典中的对应字段进行比较。如果存在(值 = 1),则循环到下一个字段并递增计数器 (i)
- 循环后,如果计数器(i)大于字段(单词)的数量,则所有单词都匹配,我们打印该行
- 循环到下一行条目
答案2
以下脚本将编译file1.txt
为grep -E
.
#!/bin/sh
regex="^($(awk '{printf $0"|"}' $1) )+\$"
grep -E "$regex" $2
用法:
$ ./script.sh file1.txt file2.txt
SORTED_RECIPS HFILTER_HELO_5
$regex
编译自file1.txt
如下:
^(ME_HTML_ONLY|SUSPICIOUS_RECIPS|SORTED_RECIPS|HFILTER_HELO_5| )+$
对于数千行file1.txt
和数file2.txt
百万行,最好使用file1.txt's
以下脚本将所有行编译成单个 awk 程序:
#!/bin/sh
for i; do
regex="^($(awk '{printf $0"|"}' $i) )+\$"
echo "/$regex/ { print \"$i: \"\$0 }"
done
例如(file1.txt's
命名为match1.txt
match2.txt
match3.txt
):
$ ./script2.sh match*.txt
/^(ME_HTML_ONLY|SUSPICIOUS_RECIPS|SORTED_RECIPS|HFILTER_HELO_5| )+$/ { print "match1.txt: "$0 }
/^(HFILTER_FROM_BOUNCE|FORGED_OUTLOOK_HTML|ANY_OTHER_WORD| )+$/ { print "match2.txt: "$0 }
/^(SORTED_RECIPS|HFILTER_HELO_5|MIME_HTML_ONLY|HFILTER_FROM_BOUNCE| )+$/ { print "match3.txt: "$0 }
$ ./script2.sh match*.txt >match.awk
$ awk -f match.awk file2.txt
match2.txt: HFILTER_FROM_BOUNCE FORGED_OUTLOOK_HTML
match1.txt: SORTED_RECIPS HFILTER_HELO_5
match3.txt: SORTED_RECIPS HFILTER_HELO_5
match3.txt: MIME_HTML_ONLY HFILTER_FROM_BOUNCE