我正在努力处理一个基本的awk命令。
文件1:
AB253828.1
AB253829.1
AB253830.1
AB253831.1
文件2:
accession accession.version taxid gi
A00001 A00001.1 10641 58418
A00002 A00002.1 9913 2
A00003 A00003.1 9913 3
A00004 A00004.1 32630 57971
A00005 A00005.1 32630 57972
A00006 A00006.1 32630 57973
A00008 A00008.1 32630 57974
A00009 A00009.1 32630 57975
A00010 A00010.1 32630 57976
两个文件都具有>1000 000条
如果第2列对应于文件1的模式,我想打印文件2的第2列和第3列我尝试了很多可能性,但都没有成功。。。
for ACC in $(cat file1.txt)
do
#ACC1=$(echo ""$ACC"")
awk -v OFS='t'-v z="$ACC" '{ if($2 == z) { print $2,$3 } }' file2.txt
done
我有
awk:无法打开{if($2==z({print$2,$3}}file2.txt(没有这样的文件或目录(
我检查了一下,文件2在那里。我想,我的问题是变量z,但我找不到答案。
直接的问题是在第二个-v
选项之前缺少一个空格。(仔细观察:您正在将OFS设置为t-v
,然后Awk认为z="$ACC"
是您的实际Awk脚本,并寻找一个名为…您的Awk剧本内容的文件,并抱怨缺少该文件。(但实际上,您需要更彻底地修改它。
awk -v OFS='t' 'NR==FNR { z[$1]++; next }
$2 in z { print $2,$3 }' file1.txt file2.txt
这使用了一个常见的Awk习惯用法,将第一个文件读取到内存中,然后从第二个文件中打印出第二个字段作为第一个文件中的条目存在的记录。这应该快几个数量级,当然也可以用for
反模式简单地修复读取线。
如果第一个文件太大,无法同时放入内存,可以将其分割成更小的部分(比如每个500000行?(,并分别在每个部分上运行。当Awk消耗了太多内存以至于系统开始崩溃时,应该很容易看到;至少在最初的几次运行中,请密切关注top
或类似的监控工具,如果进程行为不端,请终止进程。