我有一个大文件,该文件列出了一个长列unix乘以每行一个值,以0.01s的间隔递增。对于一天的数据,总计达864万行。
135699840000
135699840001
135699840002
135699840003
135699840004
我想在此文件的每一行上运行一条命令,该命令计算每行的序列日期号-来自matlab用于时间的参考年01/01/0000的天数计数器。
735235.0000000000
735235.0000001157
735235.0000002314
735235.0000003472
735235.0000004629
我是编码的新手,但是设法使用while循环使它开始工作。但是,这效率低下,需要花费数小时才能运行。
while read epochtimerange; do
echo "scale=10; (($epochtimerange/(100*86400))+719529)" |bc
done < epochtimerangetmp.txt > serialdaterangetmp.txt
我认为必须有一种使用awk运行此方法的方法,但是我无法使其正常工作。重要的是,我必须在输出中保持小数点后10位的精度。
有人可以帮我吗?谢谢。
简单的方法:ex
用于修改各行,并通过传递整个缓冲区(修改后的文件)bc
。然后打印修改后的版本。
printf '%s\n' '%s:.*:&/8640000+719529:' 0a scale=10 . '%!bc' %p 'q!' | ex file.txt
在您的样本文件上输出:
735235.0000000000
735235.0000001157
735235.0000002314
735235.0000003472
735235.0000004629
或者保存更改,而不仅仅是打印更改:
printf '%s\n' '%s:.*:&/8640000+719529:' 0a scale=10 . '%!bc' x | ex file.txt
要查看传递给ex
的printf
命令,请自己运行命令:
$ printf '%s\n' '%s:.*:&/8640000+719529:' 0a scale=10 . '%!bc' %p 'q!'
%s:.*:&/8640000+719529:
0a
scale=10
.
%!bc
%p
q!
现在让我们将它们分解为ex
命令。第一个比较复杂,因此我将特别地解释格式:
%s:.*:&/8640000+719529:
% - For every line of the buffer (file)
s - Run a substitute command
: - Using ':' as the regex delimiter
.* - Match each entire line
: - and replace with
& - The entire line, followed by
/8640000+719529 - this text
: - End command
0a
表示“在第0行之后添加文本”,换句话说,位于缓冲区(文件)的开头。
文本scale=10
是要附加的文字文本。
的.
一行由本身结束“追加”命令。
该命令%!bc
将整个缓冲区的内容作为标准输入传递给外部命令bc
,并用产生的输出替换整个缓冲区。
的%p
手段来打印整个缓冲液(标准输出)。
q!
表示不保存更改即退出。
如果您有一个非常大的文件(几千万行),这显然会带来麻烦。我已经研究了这种使用的可能解决方案,ex
并且有一些方法可以实现,但是我最终放弃了该方法,转而使用了一种简单得多的方法,该方法仍然仅使用POSIX指定的工具。
使用split
分割文件分割成块,然后运行对每个块和先前指定命令cat
的输出结果一起:
split -l 1000000 -a 3 file.txt myprefix.
for f in myprefix.???; do
printf '%s\n' '%s:.*:&/8640000+719529:' 0a scale=10 . '%!bc' %p 'q!' |
ex "$f"
done > myoutputfile.txt
rm myprefix.???
该split
命令在此处用于将file.txt
每个偶数行长的块分割成几百万行(当然,其余部分也将放入文件中)。由于-a 3
已指定,因此块上的后缀将为3个字符长。myprefix.aaa
,myprefix.aab
等等。
然后,可以单独处理每个文件ex
,而无需保存更改,因为我们将整个循环的输出重定向到myoutputfile.txt
(然后为了整洁而删除了块文件)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句