2017-06-05 124 views
4

我有我需要追加到每行的日期时间680万行(19gig)文件。我每天晚上都会得到这个文件,而且我必须将处理它的时间添加到每行的末尾。我已经尝试了许多方法来执行此操作,包括sed/awk并将其加载到SQL数据库中,最后一列默认为当前时间戳。追加日期时间每行的末尾在一个600万行的文件

我在想,如果有一个快速的方法来做到这一点?目前为止我最快的方法需要两个小时,考虑到这个文件中信息的紧迫性,这个速度还不够快。这是一个平面的CSV文件。

EDIT1:

这是我到目前为止已经完成:

awk -v date="$(date +"%Y-%m-%d %r")" '{ print $0","date}' lrn.ae.txt > testoutput.txt 

时间=117分钟

perl -ne 'chomp; printf "%s.pdf\n", $_' EXPORT.txt > testoutput.txt 

时间=135分钟

mysql load data local infile '/tmp/input.txt' into table testoutput 

时间= 211分钟

+3

你说你*已经尝试了很多方法来做到这一点,包括sed/awk *。通过展示这些方式,或许你会得到一些优化建议 – RomanPerekhrest

+0

不仅要展示你已经尝试过的方式,还必须列出每个阻碍你使用它的具体缺点。 –

+0

'我每天晚上都会得到这个文件' - 不能让你在生成时添加时间戳吗?假设答案是“否”,那么[编辑]你的问题以向我们展示你'迄今为止最快的方式'是什么,这样我们可以帮助你弄清楚它有什么问题。还包括简洁的,可测试的样本输入和预期的输出,因为并非所有的CSV都是相同的,所以我们需要知道你的样子(它可以包含字段内的逗号,它是否在字段周围使用双引号,是否在字段中转义引号通过反斜杠或加倍,字段可以包含换行符等)。 –

回答

3

,简化的解决方案摆脱所产生的空白键字段的mjuarez' helpful approach

yes "$(date +"%Y-%m-%d %r")" | paste -d',' file - | head -n "$(wc -l < file)" > out-file 

需要注意的是,与链接的答案的办法,你必须知道的数输入行预先 - 在这里我使用wc -l来计算它们,但如果数量是固定的,只需使用该固定的数字。

  • yes无限期地保持重复它的参数,每个在其自己的输出线,直到其终止。

  • paste -d',' file -糊剂相应的一对上的单个输出线从file和标准输入(-)线,与,

  • 分离自yes生产“无穷”输出,head -n "$(wc -l < file)"确保处理停止一旦所有输入线已经被处理。

使用的管道作为内存油门,所以运行内存不应该是一个问题。

0

如果你想在同一(电流)日期时间添加到每一行的文件,你还不如保留文件,因为它是,并且把日期时间的文件名来代替。根据稍后的用途,处理文件的软件可能会首先从文件名中获取日期时间。

为了把同样的日期时间,在每一行的结束,一些简单的代码可以写为:

  • 使包含分离器和日期时间的字符串。
  • 从文件中读取行,附加上面的字符串并写回新文件。

这种方式从日期时间到字符串的转换只进行一次,转换文件不应该花费比在磁盘上复制文件更长的时间。

+0

这实际上并没有提供任何答案。 OP的问题表明他们已经意识到你在这里写的几乎所有东西。仅仅因为这个问题不完整而且询问得不好,并不能给你一个提出类似答案的借口。 –

+0

@MadPhysicist对不起,但OP的回答显示,它目前需要2个小时,同时要求更快的方式。我的答案中的第二部分应该只需要5-10分钟(它也消除/防止680M日期转换,以防使用这些转换)。答案的第一部分是免费的(取决于后来的需要,将日期放在文件名中就足够了)。 –

+0

你怎么知道磁盘I/O不是这里的瓶颈(可能是) –

4

您不指定每个行的时间戳是否必须为不同。 “开始处理”时间是否足够?

如果是这样,一个简单的解决方案是使用paste命令,其中包含一个预先生成的时间戳文件,其长度与您正在处理的文件长度完全相同。然后只需将paste整个事情放在一起。另外,如果整个过程与I/O绑定,正如其他人所猜测的那样,那么可以使用SSD驱动器在盒子上运行该过程,这将有助于加速过程。

我只是想在本地在6万行的文件(大约1%你们的),它实际上能够做到这一点,在不到一秒钟,对MacBook Pro的,与SSD驱动器。

~> date; time paste file1.txt timestamps.txt > final.txt; date 
Mon Jun 5 10:57:49 MDT 2017 

real 0m0.944s 
user 0m0.680s 
sys 0m0.222s 
Mon Jun 5 10:57:49 MDT 2017 

我现在试试一个〜500万行的文件,看看这个票价是怎么回事。

更新时间:

好,结果是糊超快相比,你的解决方案,它只是在90秒总处理整个事情,600M行简单的数据了。

~> wc -l huge.txt 
600000000 huge.txt 
~> wc -l hugetimestamps.txt 
600000000 hugetimestamps.txt 
~> date; time paste huge.txt hugetimestamps.txt > final.txt; date 
Mon Jun 5 11:09:11 MDT 2017 

real 1m35.652s 
user 1m8.352s 
sys 0m22.643s 
Mon Jun 5 11:10:47 MDT 2017 

您仍然需要提前准备时间戳文件,但这是一个微不足道的bash循环。我在不到一分钟的时间里创建了我的。

+0

创建带有5亿行时间戳的文件的时间是否还需要一段时间?我会再次使用awk/perl来做到这一点。 – MichaelJC

+0

@michaelJC从字面上我花了不到一分钟的时间来创建文件。 – mjuarez

+0

@MichaelJC这是我用来创建5亿行时间戳,根据需要多次运行它:'用于'seq 1100中的数字';做猫timestamps.txt >> newtimestamps.txt;完成' – mjuarez

2

另一种替代方法,以测试是

$ date +"%Y-%m-%d %r" > timestamp 
$ join -t, -j9999 file timestamp | cut -d, -f2- 

或时间戳可以就地生成以及<(date +"%Y-%m-%d %r")

join创建第一文件和第二文件中使用不存在的场的矢量积( 9999),并且由于第二个文件只有一行,实际上将它附加到第一个文件。需要cut通过join

+0

我得到了基本相同的结果,大约90秒左右,并且没有必要预先生成一个巨大的时间戳文件,只有一个。我喜欢你的解决方案比我的更好。你能快速解释联接是如何工作的吗?在这种情况下?目前正在等待生成时间戳的结果,但我怀疑它如果有的话,会稍微慢一些。 – mjuarez

+0

我试过这个,但是我得到的内存耗尽,它花费的时间超过了90秒,而且我在一个只有1亿行的文件上 – MichaelJC

相关问题