如何在300GB .txt文件中使用awk和grep?

时间:2014-05-29 13:35:58

标签: regex unix awk grep large-files

我有一个巨大的.txt文件,300GB更精确,我想将第一列中的所有不同字符串与我的模式匹配到另一个.txt文件中。

awk '{print $1}' file_name | grep -o '/ns/.*' | awk '!seen[$0]++' > test1.txt

这是我尝试过的,据我所知,它工作正常,但问题是经过一段时间后我得到以下错误:

awk: program limit exceeded: maximum number of fields size=32767
    FILENAME="file_name" FNR=117897124 NR=117897124

有什么建议吗?

5 个答案:

答案 0 :(得分:2)

'字段数'是'列的数量'在输入文件中,如果其中一行确实长,则可能导致此错误。

我怀疑awkgrep步骤可以组合成一个:

sed -n 's/\(^pattern...\).*/\1/p' some_file | awk '!seen[$0]++' > test1.txt

这可能会完全避开awk问题(sed命令替换任何与模式匹配的前导文本,而不是整行,如果匹配,则打印出该行。< / p>

答案 1 :(得分:2)

在我看来,awk实施在一次117,897,124中可以读取的记录数有上限。限制可能因您的实施和操作系统而异。

解决此问题的一种理智方法是编写一个自定义脚本,使用split将大文件拆分为较小的文件,每个文件不超过100,000,000个记录。


如果您不想拆分文件,那么也许您可以查找与您的limits实施相对应的awk文件。也许你可以将unlimited定义为记录数值,虽然我认为这不是一个好主意,因为你最终可能会使用大量资源......

答案 2 :(得分:2)

错误消息告诉您:

line(117897124) has to many fields (>32767).

你最好查看一下:

sed -n '117897124{p;q}' file_name

使用cut提取第一列:

cut -d ' ' -f 1 < file_name | ...

注意:您可以将' '更改为字段分隔符。默认值为$'\t'

答案 3 :(得分:0)

如果你在磁盘上有足够的可用空间(因为创建了一个temp .swp文件)我建议使用Vim,vim正则表达式有一些差别,但你可以使用这个工具http://thewebminer.com/regex-to-vim <从标准正则表达式转换为vim正则表达式/ p>

答案 4 :(得分:0)

错误消息显示您的输入文件包含的awk实现字段太多。只需将字段分隔符更改为与记录分隔符相同,每行只有1个字段,因此避免出现此问题,然后将其余命令合并为一个:

awk 'BEGIN{FS=RS} {sub(/[[:space:]].*/,"")} /\/ns\// && !seen[$0]++' file_name

如果这是一个问题,请尝试:

awk 'BEGIN{FS=RS} {sub(/[[:space:]].*/,"")} /\/ns\//' file_name | sort -u

可能有一个更简单的解决方案,但由于你没有发布任何样本输入和预期输出,我们只是在猜测。