New*_*our 1 csv awk memory-leaks
我使用awk处理CSV数据文件.我的数据文件中有三个字段,例如文件a.txt.我希望awk从另一个文件b.txt中读取一个字段,然后如果第一列与读取的表达式匹配b.txt,则从我的a.txt中写入该行.我发现以下内容可以做我想要的.
awk 'BEGIN {FS=","} { while(getline l < "b.txt") PATS[l] }ok=0;{for (p in PATS) if ($1 ~ p) ok=1}; ok {print $0}' < a.txt
Run Code Online (Sandbox Code Playgroud)
但是,我得到了巨大的内存泄漏,程序退出时出现内存错误.a.txt约为41000行.如果有人能指出我的记忆力和/或提出替代解决方案,我将不胜感激.
使用getline验证两个文件这样是不是一个伟大的想法,很可能是你的问题的根本原因.有许多getline功能的警告,即使它是一个很好的工具,它经常被误用.
我建议使用awk内置变量NR并FNR扫描b.txt文件并将其存储在数组中.一旦你已经加载了数组,你可以检查$1从a.txt如果你的阵列的密钥相匹配.
就像是:
awk -F, 'NR==FNR{PATS[$0]++;next}$1 in PATS' b.txt a.txt
Run Code Online (Sandbox Code Playgroud)
请注意我在awk命令之后放置了两个文件.这样做,直到NR和FNR相同(对于第一个文件只相同,在第一个文件完成后,FNR将重置为1)我们创建一个名为的数组PATS并使用整行作为键.next阻止第二个awk语句运行.一旦b.txt完成,我们移动到a.txt文件并寻找$1你的阵列中的存在.如果是,它将评估1并打印该行.如果$1您的数组中不存在,则它将评估为false并且不打印该行.
上面的命令会查找完全匹配.我看到你使用了匹配运算符~,这也意味着部分匹配.如果那就是你想要的那么你就可以做到:
awk -F, 'NR==FNR{PATS[$0]++;next}{for(p in PATS) if($1~p) print $0}' b.txt a.txt
Run Code Online (Sandbox Code Playgroud)
如果这不适合你,我建议从这两个文件中发布一些样本数据.