Awk 将日期时间追加到6亿行文件中每行的末尾

Awk 将日期时间追加到6亿行文件中每行的末尾,awk,sed,bigdata,Awk,Sed,Bigdata,我有一个6.8亿行(19gig)的文件,我需要在每一行追加日期时间。我每天晚上都会收到这个文件,我必须把处理它的时间加到每行的末尾。我尝试了很多方法,包括sed/awk,并将其加载到SQL数据库中,最后一列默认为当前时间戳 我想知道是否有一个快速的方法来做到这一点?到目前为止,我最快的方法需要两个小时,考虑到这个文件中信息的紧迫性,这还不够快。它是一个平面CSV文件 编辑1: 以下是我迄今为止所做的工作: awk -v date="$(date +"%Y-%m-%d %r")" '{ print

我有一个6.8亿行(19gig)的文件,我需要在每一行追加日期时间。我每天晚上都会收到这个文件,我必须把处理它的时间加到每行的末尾。我尝试了很多方法,包括sed/awk,并将其加载到SQL数据库中,最后一列默认为当前时间戳

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

编辑1:

以下是我迄今为止所做的工作:

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

Time=211分钟

如果要向文件中的每一行添加相同的(当前)日期时间,最好保持文件原样,将日期时间改为文件名。根据以后的使用情况,处理文件的软件可以首先从文件名中获取日期时间

要将相同的datetime放在每行的末尾,可以编写一些简单的代码:

  • 创建一个包含分隔符和日期时间的字符串
  • 读取文件中的行,附加上面的字符串并写回新文件

这样,从datetime到字符串的转换只需执行一次,并且转换文件的时间不应比在磁盘上复制文件的时间长太多。

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

如果是这样,一个简单的解决方案是使用
paste
命令,使用预先生成的时间戳文件,其长度与您正在处理的文件完全相同。然后把整个东西粘贴在一起。另外,如果像其他人猜测的那样,整个过程都是I/O绑定的,那么在带有SSD驱动器的机箱上运行此操作可能有助于加快过程

我只是在一个600万行的文件(大约是你的1%)上进行了本地测试,实际上它可以在不到一秒钟的时间内完成,在MacBookPro上,使用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
我现在要尝试一个~5亿行的文件,看看效果如何

更新:

好的,结果出来了。与您的解决方案相比,粘贴速度非常快,总共只需90秒就可以处理整个过程,6亿行简单数据

~> 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循环。我在不到一分钟的时间内创建了我的。测试的另一个替代方法是

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

或者也可以就地生成时间戳
,这是一种简化以下内容的解决方案:

yes“$(日期+%Y-%m-%d%r”)”、“粘贴-d”、“文件-|头-n“$(wc-lout文件
请注意,与链接答案中的方法一样,您必须提前知道输入行的数量-这里我使用
wc-l
来计算它们,但是如果数字是固定的,只需使用固定的数字即可

  • yes
    在各自的输出行上无限期地重复其参数,直到终止

  • paste-d',“file-
    file
    和stdin(
    -
    )中的一对对应行粘贴到单个输出行上,用
    分隔

  • 由于
    yes
    产生“无止境”输出,
    head-n“$(wc-l
    确保在处理完所有输入行后停止处理


管道的使用起到了内存节流的作用,因此内存不足不应该成为一个问题。

您说过,您已经尝试了很多方法来实现这一点,包括sed/awk。展示这些方法,也许,你会得到一些优化建议。你不仅必须展示你尝试过的方法,还必须列出每一种方法的具体缺点,这些缺点阻止你使用它。
我每天晚上都会收到这个文件
-你能不能让生成它的人在他们这样做时添加时间戳?假设答案为“否”,您的问题将向我们展示迄今为止您的
最快方法是什么,以便我们可以帮助您找出问题所在。还包括简洁、可测试的示例输入和预期输出,因为并非所有CSV都是相同的,所以我们需要知道您的CSV是什么样子的(它是否可以在字段内包含逗号,是否在字段周围使用双引号,是否通过反斜杠或双引号转义字段内的引号,字段是否可以包含换行符,等等)。向所有记录添加相同的时间戳的基本原理是什么?
perl-lnse'print$,,,,$date'--date=“$(date”+%F%r”)“infle>outfile
可能比当前的perl命令稍快。这实际上并没有提供任何类型的答案。OP的问题表明他们已经知道你在这里写的几乎所有东西。仅仅因为这个问题不完整且问得不好,并不能给你一个做出类似回答的借口。@MadPhysician,我很抱歉,但OP的回答表明目前需要2个小时,同时要求更快的方法。我回答的第二部分应该只需要5-10分钟(如果使用了6.8亿次日期转换,它还可以消除/阻止这些转换)。答案的第一部分是免费的(取决于以后的需要,在文件名中输入日期就足够了)。你怎么知道磁盘I/O不是这里的瓶颈(很可能是)@MadPhysical 5-10分钟实际上是磁盘I/O(读写19GB)。将准备好的字符串追加到每一行不会增加太多的处理时间(因为它无论如何都是I/O绑定的)。创建具有5亿行时间戳的文件不会也需要一段时间吗?我会再次使用awk/perl来做这件事。@michaelJC创建文件的时间实际上不到一分钟。@michaelJC这就是我用来创建5亿行时间戳的东西,需要多少次就运行多少次:
对于
seq 1 100
中的数字;你喜欢猫吗
yes "$(date +"%Y-%m-%d %r")" | paste -d',' file - | head -n "$(wc -l < file)" > out-file