awk
可以生成带有strftime函数的时间戳,例如
$ awk 'BEGIN {print strftime("%Y/%m/%d %H:%M:%S")}'
2019/03/26 08:50:42
但是我需要一个带有小数秒的时间戳,理想情况下可以降至纳秒。 gnu date
可以使用%N
元素:
$ date "+%Y/%m/%d %H:%M:%S.%N"
2019/03/26 08:52:32.753019800
但是与调用date
相比,从awk
内调用strftime
效率相对较低,并且我需要高性能,因为我正在使用awk
处理许多大文件并且在处理文件时需要生成许多时间戳。 awk
是否可以有效地生成包括小数秒(理想情况下为纳秒,但可以接受毫秒)的时间戳?
添加我要执行的操作的示例:
awk -v logFile="$logFile" -v outputFile="$outputFile" '
BEGIN {
print "[" strftime("%Y%m%d %H%M%S") "] Starting to process " FILENAME "." >> logFile
}
{
data[$1] += $2
}
END {
print "[" strftime("%Y%m%d %H%M%S") "] Processed " NR " records." >> logFile
for (id in data) {
print id ": " data[id] >> outputFile
}
}
' oneOfManyLargeFiles
答案 0 :(得分:2)
如果您确实需要亚秒级的计时,那么对外部命令(如date
的任何调用或读取外部系统文件(如/proc/uptime
或/proc/rct
的调用都将无法达到目的)亚秒精度。两种情况都需要大量资源来检索所请求的信息(即时间)
由于OP已经使用GNU awk,因此可以使用动态扩展。动态扩展是一种通过实现用C或C ++编写的新函数并使用gawk动态加载它们来向awk添加新功能的方法。 GNU awk manual中广泛记录了如何编写这些功能。
幸运的是,GNU awk 4.2.1附带了一组默认动态库,可以随意加载它们。这些库之一是time
库,它具有两个简单的功能:
the_time = gettimeofday()
以秒为单位返回自1970-01-01 UTC以来经过的时间(以秒为单位)。如果时间在该平台上不可用,请返回-1
并设置ERRNO
。 返回的时间应具有亚秒精度,但实际精度可能会因平台而异。如果标准Cgettimeofday()
系统调用在此平台上可用,则它仅返回该值。否则,如果在MS-Windows上,它将尝试使用GetSystemTimeAsFileTime()
。
result = sleep(seconds)
尝试睡眠seconds
秒。如果seconds
为负,或尝试睡眠失败,请返回-1
并设置ERRNO
。否则,在指定的时间内睡眠后返回零。请注意,秒可能是浮点(非整数)值。实现细节:根据平台的可用性,此函数尝试使用nanosleep()
或select()
来实现延迟。
现在可以以相当简单的方式调用此函数:
awk '@load "time"; BEGIN{printf "%.6f", gettimeofday()}'
1553637193.575861
为了证明该方法比更经典的实现更快,我使用gettimeofday()
对所有3个实现进行了计时:
awk '@load "time"
function get_uptime( a) {
if((getline line < "/proc/uptime") > 0)
split(line,a," ")
close("/proc/uptime")
return a[1]
}
function curtime( cmd, line, time) {
cmd = "date \047+%Y/%m/%d %H:%M:%S.%N\047"
if ( (cmd | getline line) > 0 ) {
time = line
}
else {
print "Error: " cmd " failed" | "cat>&2"
}
close(cmd)
return time
}
BEGIN{
t1=getimeofday(); curtime(); t2=gettimeofday();
print "curtime()",t2-t1
t1=getimeofday(); get_uptime(); t2=gettimeofday();
print "get_uptime()",t2-t1
t1=getimeofday(); gettimeofday(); t2=gettimeofday();
print "gettimeofday()",t2-t1
}'
输出:
curtime() 0.00519109
get_uptime() 7.98702e-05
gettimeofday() 9.53674e-07
虽然curtime()
在加载外部二进制文件时最慢,但令人惊讶的是看到awk在处理额外的外部/ proc /文件方面速度飞快。
答案 1 :(得分:1)
如果您使用的是Linux,则可以使用/proc/uptime
:
$ cat /proc/uptime
123970.49 354146.84
得到一些厘秒(第一个值是正常运行时间),并计算开始时间与发生任何事情之间的时间差:
$ while true ; do echo ping ; sleep 0.989 ; done | # yes | awk got confusing
awk '
function get_uptime( a) {
if((getline line < "/proc/uptime") > 0)
split(line,a," ")
close("/proc/uptime")
return a[1]
}
BEGIN {
basetime=get_uptime()
}
{
if(!wut) # define here the cause
print get_uptime()-basetime # calculate time difference
}'
输出:
0
0.99
1.98
2.97
3.97