如何在bash中将列中的日期转换为历元时间戳?
我有一个包含以下内容的文件:如何在bash中将列中的日期转换为历元时间戳?,bash,unix,awk,Bash,Unix,Awk,我有一个包含以下内容的文件: 2014-11-10 02:00:03,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22 2014-11-10 02:00:07,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22 2014-11-10 02:00:11,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52
2014-11-10 02:00:03,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22
2014-11-10 02:00:07,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22
2014-11-10 02:00:11,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52506,22
我想将时间戳转换为以下格式的日期:
1415602803,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22
1415602807,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22
1415602811,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52506,22
如何使用awk或任何其他bash工具实现这一点
背景:
我需要从hdfs获取特定时间范围内的文件。最初,我使用hdfs dfs-stat来实现划时代,然后编写一个过滤器
cat <fileWithFilePaths> | xargs -I ^ -P 15 sh -c 'printf "%s\n" "$(hdfs dfs -stat "%n,%Y,%b" ^)"'>output1
awk 'BEGIN{beginDE=ENVIRON["beginDataEpoch"]; endDE=ENVIRON["endDataEpoch"]; FS="@"} {if ($1 >= beginDE && $1 <= endDE) print $0}' output1
cat | xargs-I^-p15 sh-c'printf“%s\n”“$(hdfs-stat“%n,%Y,%b”^)”>output1
awk'beginDE{beginDE=ENVIRON[“beginDataEpoch”];endDE=ENVIRON[“endDataEpoch”];FS=“@”}{如果($1>=beginDE&&$1,我想读循环是最简单的。
以下是:
while IFS=, read -r date rest; do
printf "%s,%s\n" "$(date --date="$date" +%s)" "$rest"
done <<EOF
2014-11-10 02:00:03,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22
2014-11-10 02:00:07,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22
2014-11-10 02:00:11,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52506,22
EOF
如果您的日志文件很大,那么这个GNUawk
命令将比为每行调用外部命令date
的bash
循环快得多:
gawk -vFS=, -vOFS=, '{ $1 = mktime(gensub("[-:]", " ", "g", $1)) } 1'
- 第一个逗号分隔的字段将替换为
mktime
的结果,这是一个函数(GNU扩展名),该函数以自EPOCH起的秒数返回其参数
gensub
(GNU扩展)用于将“YYYY-MM-DD hh:MM:ss
”转换为“yyy-MM-DD hh-MM ss
”,这是mktime()所期望的格式
- 最后的
1
仅仅是输出该行的真实条件
您可以使用
awk
及其内置的gensub
、mktime
和sub
来完成相同的任务,例如:
$ awk -F, '{ str=$0; sub($1, mktime(gensub(/[-:]/, " ", "g", $1)), str); print str }' file
1415606403,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22
1415606407,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22
1415606411,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52506,22
说明:
gensub(/[-:]/,“”,“,”g“,$1)
-将第一个字段中的所有'-'
和':'
替换为空格
mktime(…)
-将结果日期转换为时间戳
str=$0;sub($1,…,str);
-将第一个字段替换为时间戳,结果为str
;最后
打印str
-打印它
(注意:您的时区和my的时区相差3小时。您的输出应该会在您的系统上为您提供所需的结果。您还可以调整夏令时的mktime
(如果需要),并且您可以使用内置的strftime
和utc标志来调整utc。)我也遇到了同样的问题,当时我需要将一些历史股票数据中的日期转换为unix时间。使用了这个sed
和date
命令。请注意,这只在Linux上有效(GNU实现sed
和date
)
你的时间是格林尼治标准时间,还是你知道时区?你所要求的不是使用传统的awk,而是可能使用bash中的gawk或函数。也就是说,我投票结束这个问题,因为你似乎在寻求解决方案,而不是代码方面的帮助。如果你确实有一些代码需要帮助,请租赁,我将很高兴地撤回我的投票。我使用当地时间(EST)。是的,我正在寻求代码方面的帮助,提供的代码片段与我在代码中的代码片段类似。据说我不明白我的问题为什么会被否决。下面提供的解决方案对我的用例非常有用。问题是,你没有在问题中提供代码片段。你正在获得否决票并关闭votes,因为您的问题似乎是一个分发请求,而不是从您自己尝试解决这个问题开始。要显示您迄今为止的工作,请创建一个列表,以便回答您的问题的人知道您的挑战所在。date
命令在我的系统上不包括--date
选项。您可以调整您的解决方案以使其更有效吗可移植,或仅限于问题中包含的语言?可能是date-d“$date”+%s
?不可以。-f
选项将用于从可预测的格式解释日期,并且-v
可用于应用调整。Och很酷,您已经打开了BSD。尝试类似于date-j-f'%Y-%m-%d%H:%m:%s'$date的smth+%s
?当然可以,甚至日期-j-f“%f%T'”$date“+%s”
。但更重要的是,OP使用的是什么操作系统?他/她没有说,没有提供任何提示的示例代码,并要求提供一个bash/awk解决方案。与其解决这个问得不好的问题中的未知问题,我建议投票关闭它,并鼓励OP改进这个问题或提出一个问题下次再做一次更好。如果你否决了一个技术上正确的答案,请诚实地留下一条评论,指出你认为不正确的部分——这是一种常见的礼貌,如果没有其他原因的话。谢谢你。这似乎是半随机的。总有一些人不明白我们都是来学习和帮助彼此的,但事实并非如此tead将其视为“喜欢”或“不喜欢”的问题——这与网站的目的不符,也打折了可以学习的东西。自从向下投票开始花费向下投票人一分后,情况变得更好了,但仍有改进的余地。@EdMorton——你也注意到了。这似乎是一个可以解决的问题。我只是不知道et这种心态……我不能代表下一个投票人说话,但我不得不注意到这个答案在技术上是不正确的。gensub
和mktime
都不是awk的一部分,它们是gawk的一部分。我在问题中看不到任何东西表明OP正在使用什么操作系统或awk的种类,所以我希望答案也能满足问题中规定的基本标准,或者明确限制。不是每个人都说你的方言。你暗示这是在Linux上的吗?问题中肯定没有提到。或者你假设Linux是唯一一个人们使用bash的地方吗?即便如此,awk!=gawk,你回答的第一句话我这仍然是不正确的。虽然这段代码可能会解决这个问题,但如何以及为什么解决这个问题将真正有助于提高你的帖子质量,并可能导致更多的投票。记住,你是
$ awk -F, '{ str=$0; sub($1, mktime(gensub(/[-:]/, " ", "g", $1)), str); print str }' file
1415606403,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22
1415606407,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22
1415606411,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52506,22
simon@debian:~/Downloads$ cat inputFile
2014-11-10 02:00:03,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22
2014-11-10 02:00:07,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22
2014-11-10 02:00:11,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52506,22
simon@debian:~/Downloads$
simon@debian:~/Downloads$
simon@debian:~/Downloads$
simon@debian:~/Downloads$ sed 's/20[0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]/echo `date --date="&" +"%s"`/e' inputFile > output
simon@debian:~/Downloads$
simon@debian:~/Downloads$
simon@debian:~/Downloads$
simon@debian:~/Downloads$ cat output
1415602803,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22
1415602807,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22
1415602811,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52506,22