我在文件中有一个列表如下(实际上大约335 K):
abc
efg
hij
我想在一些文件中查找此列表的存在 - 所有文件都具有相同的.count扩展名,这样我的输出就是每个.count中上面列表的二进制计数是什么档案:
abc 1
efg 0
hij 1
(只给我一个目前的二进制分数为1,缺席的分数为0) 在我的代码中,我循环遍历每个文件,扩展名为.count,并查找上面列表中的字符的二进制分数,我正在寻找如下:
awk -v lookup="$block" '$1 == lookup {count++ ; if (count > 0) exit} END {if (count) print 1 ; else print 0}' $file.count
查找是永远的,我想知道是否有另一种方法可以加快查找速度?
答案 0 :(得分:2)
首先,这没有多大意义
{count++ ; if (count > 0) exit}
你能明白为什么吗?
其次,您可以通过将查找加载到数组中来减少循环,例如,
awk 'NR==FNR{a[$1];next} {print $1 in a}' lookupfile otherfiles*
将打印每行的1/0位数
也可以打印ID
awk 'NR==FNR{a[$1];next} {print $1, $1 in a}' lookupfile otherfiles*
更新:修正错误
为你的例子
$ echo -e "abc\ndef\nghi" > lookup
$ echo ghi > file1
$ awk 'NR==FNR{a[$1];next} {print $1, $1 in a}' lookup file1
ghi 1
UPDATE2:增强示例
如果订单无关紧要会更容易,但这也会保留订单,并且可以同时运行多个文件。您可以调整打印标题(打印f)
使用此设置
$ echo -e "abc\ndef\nghi" > lookup
$ echo ghi > file1
$ echo abc > file2
你可以运行
$ awk 'NR==FNR{a[NR]=$1;c++;next}
FNR==1 && f{print f;
for(k=1;k<=c;k++) print a[k], a[k] in b; delete b}
{b[$1]; f=FILENAME}
END{print f;
for(k=1;k<=c;k++) print a[k], a[k] in b; delete b}' lookup file1 file2
file1
abc 0
def 0
ghi 1
file2
abc 1
def 0
ghi 0
<强>解释强>
第一个之后每个文件开头的
NR==FNR{a[NR]=$1;c++;next}
用于将查找表加载到数组中 按顺序(awk数组实际上是哈希结构和迭代顺序 可以是随机的)并计算条目数。
FNR==1 && f{print f;
一个打印文件名
for(k=1...) print a[k], a[k] in b; delete b}
遍历查找 表顺序并检查之前处理的文件是否有相应的条目并删除处理后的文件值(在b中)
{b[$1]; f=FILENAME}
加载每个文件的条目并设置 文件名(将在上面用于在第一个之后推迟打印) 文件)
END{print f; ...
上面说明了同样的印刷步骤 文件。