更快的查找 awk 的方法

Faster way to lookup awk

我在文件中有一个列表如下(实际大约335K):

      abc
      efg 
      hij

我想在某些文件中查找此列表的存在 - 所有这些文件都具有相同的扩展名 .count 这样我的输出将是即每个 .count 文件中上述列表的二进制计数是多少:

    abc 1
    efg 0
    hij 1

(只给我二进制分数 1 代表出席,0 代表缺席) 在我的代码中,我循环遍历每个扩展名为 .count 的文件,并寻找上面字符列表的二进制分数,我正在寻找它如下:

 awk -v lookup="$block" ' == lookup {count++ ; if (count > 0) exit} END {if (count) print 1 ; else print 0}' $file.count

查找需要很长时间,我想知道是否有其他方法可以加快查找速度?

首先,这没有多大意义

{count++ ; if (count > 0) exit}

你能看出原因吗?

其次,您可以通过将查找加载到数组中来减少循环,例如,

awk 'NR==FNR{a[];next} {print  in a}' lookupfile otherfiles*

将打印每行的 1/0 数字

也打印 ID

awk 'NR==FNR{a[];next} {print ,  in a}' lookupfile otherfiles*

更新:修正了拼写错误

举个例子

$ echo -e "abc\ndef\nghi" > lookup
$ echo ghi > file1
$ awk 'NR==FNR{a[];next} {print ,  in a}' lookup file1
ghi 1

UPDATE2: 增强示例

如果顺序无关紧要会更容易,但这也保留了顺序并且可以同时 运行 多个文件。您可以调整打印 header (print f)

使用此设置

$ echo -e "abc\ndef\nghi" > lookup
$ echo ghi > file1
$ echo abc > file2

你可以运行

$ awk 'NR==FNR{a[NR]=;c++;next} 
   FNR==1 && f{print f;
               for(k=1;k<=c;k++) print a[k], a[k] in b; delete b}
              {b[]; 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

Explanation

NR==FNR{a[NR]=;c++;next} is for loading up the lookup table into array in order (awk arrays are actually hash structures and iteration order can be random) and count the number of entries.

FNR==1 && f{print f; at the beginning of each file after the first one print the filename

for(k=1...) print a[k], a[k] in b; delete b} iterate over the lookup table in order and check the file processed before has the corresponding entry and remove the processed file values (in b)

{b[]; f=FILENAME} load up the entries for each file and set the filename (which will be used above to defer printing after the first file)

END{print f; ... same printing step explained above now for last file.