查找以毫秒为单位的时差awk或gawk
我将包含大量数据的文件转换为以下格式,我想找出以毫秒为单位的两个时间戳之间的差异,并在最后添加一列,显示该行的时间差异查找以毫秒为单位的时差awk或gawk,awk,Awk,我将包含大量数据的文件转换为以下格式,我想找出以毫秒为单位的两个时间戳之间的差异,并在最后添加一列,显示该行的时间差异 22159 | a | 2021-02-26 11:02:03.776 | 2021-02-26 11:02:04.740 22160 | b | 2021-02-26 11:35:21.796 | 2021-02-26 11:35:22.674 22161 | c | 2021-02-26 11:35:21.806 | 2021-02-26 11:35:22.841 2216
22159 | a | 2021-02-26 11:02:03.776 | 2021-02-26 11:02:04.740
22160 | b | 2021-02-26 11:35:21.796 | 2021-02-26 11:35:22.674
22161 | c | 2021-02-26 11:35:21.806 | 2021-02-26 11:35:22.841
22161 | d | 2021-02-26 11:02:18.688 | 2021-02-26 11:02:19.594
22182 | e | 2021-02-26 11:06:02.978 | 2021-02-26 11:06:03.815
22183 | f | 2021-02-26 11:35:24.911 | 2021-02-26 11:35:25.791
22184 | g | 2021-02-26 11:35:25.082 | 2021-02-26 11:35:26.121
22199 | h | 2021-02-26 11:09:47.815 | 2021-02-26 11:09:48.499
22200 | i | 2021-02-26 11:35:27.562 | 2021-02-26 11:35:28.660
22200 | j | 2021-02-26 11:09:49.595 | 2021-02-26 11:09:50.596
输出,输出
9535a 2021-02-27 11:02:53.756 2021-02-27 11:02:53.947 0.191
我的命令如下:
awk -F'|' 'function convert(t) { cmd = "date +%s.%3N -d \""t"\" "; cmd|getline timemilli; return timemilli; } { t2=convert($4);t1=convert($3);printf $1"\t"$2"\t"$3"\t"$4"\t%.3f\n",t2-t1 }' filtered_data
它的工作很好的小文件,但它给了我错误的大文件
错误:
awk:cmd。第1行:(FILENAME=filtered_data FNR=516)致命:无法打开管道date+%s.%3N-d“2021-02-27 11:24:05.618”(打开的文件太多)`
注意:我的文件大约是10MB,我想找出单个快照中的差异。不在每条线上循环
在单次拍摄中还有其他方法吗?使用GNU awk,因为
mktime()
和gensub()
:
输出:
22159 a 2021-02-26 11:02:03.776 2021-02-26 11:02:04.740 -0.964
22160 b 2021-02-26 11:35:21.796 2021-02-26 11:35:22.674 -0.878
22161 c 2021-02-26 11:35:21.806 2021-02-26 11:35:22.841 -1.035
...
注意:
mktime()
需要时间,格式为“YYYY-MM-DD-HH-MM-SS[DST]”
。上面我正在滥用(由于懒惰)并以格式“YYYY-MM-DD-HH-MM-SS-sss”
将其输入,其中sss
是毫秒。它似乎可以工作,但您可能需要使用例如substr()
或类似的工具来解决此问题。使用GNU awk,因为mktime()
和gensub()
:
输出:
22159 a 2021-02-26 11:02:03.776 2021-02-26 11:02:04.740 -0.964
22160 b 2021-02-26 11:35:21.796 2021-02-26 11:35:22.674 -0.878
22161 c 2021-02-26 11:35:21.806 2021-02-26 11:35:22.841 -1.035
...
注意:
mktime()
需要时间,格式为“YYYY-MM-DD-HH-MM-SS[DST]”
。上面我正在滥用(由于懒惰)并以格式“YYYY-MM-DD-HH-MM-SS-sss”
将其输入,其中sss
是毫秒。它似乎可以工作,但您可能需要使用例如substr()
或类似的工具来修复此问题。您可以尝试此awk
:
awk-F'|''
函数转换(t、cmd、timemilli){
cmd=“日期+%s.%3N-d\”“t”
cmd | getline timemilli
关闭(cmd)#关闭此cmd以避免打开过多文件
返回时间毫秒
}
{
t2=转换(4美元)
t1=转换(3美元)
打印文件“%s\t%.3f\n”,“1”\t“$2”\t“$3”\t“$4,t2-t1
}“过滤的数据”
您可以试试这个awk
:
awk-F'|''
函数转换(t、cmd、timemilli){
cmd=“日期+%s.%3N-d\”“t”
cmd | getline timemilli
关闭(cmd)#关闭此cmd以避免打开过多文件
返回时间毫秒
}
{
t2=转换(4美元)
t1=转换(3美元)
打印文件“%s\t%.3f\n”,“1”\t“$2”\t“$3”\t“$4,t2-t1
}“过滤的数据”
用于mawk
1.3.4。参见mktime
上的mawk文档了解
夏令时dst
LC_ALL=C awk -v FS=' +\| ' -v OFS='|' -v RS=' <br/>\n' -v OFMT='%.3f' -v dst='-1' '
function fn(s) {
# return epoch seconds, with milliseconds as fraction
gsub(/-|:/," ",s)
return mktime(substr(s,1,19) " " dst) + substr(s,21,3)/1000
}{ $(NF+1) = fn($4) - fn($3) }
1
' data
LC\u ALL=C awk-vfs='+\\\\'-vofs=''\\\\'-vrs='
\n'-vofmt='%.3f'-vdst='-1''
功能fn(s){
#返回以毫秒为分数的历元秒数
gsub(/-:/,“”,s)
返回mktime(substr(s,1,19)”“dst)+substr(s,21,3)/1000
}{$(NF+1)=fn($4)-fn($3)}
1.
"数据,
EDIT编辑FS
和RS
以匹配OP的新输入格式。用于mawk
1.3.4。参见mktime
上的mawk文档了解
夏令时dst
LC_ALL=C awk -v FS=' +\| ' -v OFS='|' -v RS=' <br/>\n' -v OFMT='%.3f' -v dst='-1' '
function fn(s) {
# return epoch seconds, with milliseconds as fraction
gsub(/-|:/," ",s)
return mktime(substr(s,1,19) " " dst) + substr(s,21,3)/1000
}{ $(NF+1) = fn($4) - fn($3) }
1
' data
LC\u ALL=C awk-vfs='+\\\\'-vofs=''\\\\'-vrs='
\n'-vofmt='%.3f'-vdst='-1''
功能fn(s){
#返回以毫秒为分数的历元秒数
gsub(/-:/,“”,s)
返回mktime(substr(s,1,19)”“dst)+substr(s,21,3)/1000
}{$(NF+1)=fn($4)-fn($3)}
1.
"数据,
EDIT编辑了FS
和RS
,以匹配OP的新输入格式。错误消息似乎表明有多个打开的文件,但您只有一个非常大的文件,对吗?是的。我只打开一个文件。对于某些条目,它似乎给出了错误的差异:775875 a 2021-02-27 12:01:44.231 2021-02-27 12:01:44.454 0.000我认为错误消息与使用了许多不带。请参阅@anubhava的答案。当您使用GNU特定选项(-d
和%N
)时,显然您有GNU日期,因此您必须也有GNU awk可用,但当您有太多打开的输出文件或管道时,GNU awk不会失败,它只会减慢速度,因此尽管它可用,但您不会调用它。因此,只要调用GNU awk而不是您正在调用的任何awk,就可以避免该错误,但是如果你有GNU awk,有一个更好的方法来做你想做的事情,那就是使用它的内置时间函数,而不是在每个输入行生成一个子shell来调用date
两次。在少数情况下,调用getline
是正确的方法,您应该在使用仅在成功时才填充的变量之前测试其成功/失败结果,有关详细信息,请参阅。错误消息似乎表明有多个打开的文件,但您只有一个真正大的文件,对吗?是的。我只打开一个文件。对于某些条目,它似乎给出了错误的差异:775875 a 2021-02-27 12:01:44.231 2021-02-27 12:01:44.454 0.000我认为错误消息与使用了许多不带。请参阅@anubhava的答案。当您使用GNU特定选项(-d
和%N
)时,您显然有GNU日期,因此您也必须有GNU awk可用,但GNU awk不会fai