更快的查找 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.
我在文件中有一个列表如下(实际大约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.