我有一个4 gig CSV,我试图搜索以获得CSV的子集。我有一个文件CSV文件,其中包含我要搜索的关键字(这些关键字将在大CSV的第一列)。
我尝试了这一行,但它最终花了一个多小时才完成。我需要使用tr来摆脱windows返回char。
LC_ALL=C grep -F -i -f <(tr -d '\r' < keywords.csv) big_csv.csv > output.csv
字符串
有没有什么我可以优化的地方?有没有什么我遗漏的地方?使用awk或者其他工具会更好?我甚至想过排序,然后将大的csv按第一行分割,这样当我搜索的时候,我就可以按文件名搜索关键字,然后将其附加到一个新文件中。有没有最佳实践?我试图尽可能地使其成为POSIX
这里所要求的是一些样本数据。
ADLV,-1.741774,0.961072,-0.751392,-0.935572,-2.269994,1.081103,-0.831244,1.540083,0.474326,-1.322924,2.199037,-0.919939,0.641496,-0.584152,0.729028,0.608351,-0.522026,0.966026,-0.793949,-1.623368,1.16177,-0.642438,-0.675811,-0.214964,-2.263053,2.188642,0.302449,0.770106
型
第一行将有多个条目。
有更多的数据在行中,但它太长,无法张贴在这里。
关键字文件如下所示
ADLV
ADVG
型
在最多的关键字.csv将有1,000个关键字。他们都将是每个关键字4个字母。
以下是示例数据https://gist.github.com/fishnibble/9d95658c352a1acab3cec3e965defb3f的要点
6条答案
按热度按时间hc8w905p1#
使用任何awk,听起来你所需要的就是:
字符串
sub(/\r$/,"")
在那里是因为你的代码中有tr -d '\r' < keywords.csv
-如果你的关键字文件中没有DOS行结束符,那么你不需要它。我看到你在grep命令中也有
-i
,这意味着你需要使匹配的大小写不敏感-如果是这样,那么这就是你需要的,仍然使用任何awk:型
您尝试的
grep
行不仅需要很长时间才能完成,而且还可能产生不正确的输出,因为它搜索big_csv的整行,而不仅仅是第一个字段,因此如果关键字出现在行中的其他位置,它将生成错误匹配,如果您想要的关键字碰巧是其他关键字的子字符串,它也将生成错误匹配。y1aodyip2#
这就是你在awk中的做法。我很想看看持续时间是长了还是短了。
字符串
它的工作原理是使用常见的“第一个文件”测试将第一个文件阅读到一个数组中,然后将该数组作为第二个文件的键进行检查。
我可以进一步更新,如果你添加更多的细节到你的问题。
vbkedwbf3#
假设条件:
keywords.csv
的数据可能具有windows/dos行结尾(\r
)设置:
字符串
一个基本的
awk
方法:型
这将产生:
型
eqfvzcg84#
假设:密钥在两个文件的第1列中(
big.csv
,keys.txt
来自示例数据)字符串
给出:
型
(for为了可读性,我只是打印了前两列用于匹配密钥)
我不是一个母语为英语的人,所以对于NR,FNR,数组和这里发生的所有事情的解释,我想参考this discussion。
希望这有帮助!
wz1wpwve5#
在Ruby中也可以这样做:
字符串
用Ruby做基本的例子并没有什么特别的优势。事实上,如果实际的使用只是你所描述的那样,我会用awk来做。Ruby可能会更快,但通常不会。
然而,你可以做一些事情,比如输出到不同的格式(JSON、XML、复杂的CSV),这些在awk中是有挑战性的,在Ruby中更容易完成。
你可以在Ruby内部复制
curl
,并直接阅读你的gist示例:型
这就是你想要Ruby / Python / Perl的地方,因为在awk中很难做到这一点。你也可以挂载外部服务器或读取ftp等,这些都是awk * 单独 * 的挑战。
ubby3x7f6#
有什么我可以优化的吗?有什么我遗漏的吗?
您命令GNU
grep
在整行中查找关键字。这是不必要的,因为您希望在第一列中找到具有该关键字的行,对于第一列中没有引号的CSV,这意味着行以关键字开头,后跟逗号(,
)字符。使用awk或其他工具会更好吗?
如果你时间有限,你应该准备一个更小的例子,然后测量各种解决方案。由于
awk
解决方案已经显示,我将提出GNUsed
解决方案,通过修改你的关键字文件,比如keywords.txt
字符串
通过执行
sed -e 's/^/\/^/' -e 's/[\r\n]*$/,\/p/' keywords.txt > file.sed
,型
这将创建
file.sed
,可以如下使用型
说明:
-n
解除默认打印操作-f file.sed
执行file.sed
中的命令,在这种情况下,这些只是p
打印。