我有一个包含以下内容的文件:
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
但是后来意识到使用hdfs stat是昂贵的功能。因此,现在我正在使用 hdfs dfs -ls 来增加文件时间,但采用yyyy-mm-dd hh:mm格式,因此我正在寻求帮助以缩短时间以减少计算时间线。
答案 0 :(得分:2)
如果您的日志文件很大,那么此GNU awk
命令将比bash
循环为每一行调用外部命令date
的速度快得多:
gawk -vFS=, -vOFS=, '{ $1 = mktime(gensub("[-:]", " ", "g", $1)) } 1'
mktime
的结果所代替,gensub
是一个函数(GNU扩展名),其返回的参数为自EPOCH以来的秒数。YYYY-MM-DD hh:mm:ss
(GNU扩展名)用于将“ YYYY MM DD hh mm ss
”转换为“ mktime()
”所期望的格式“ 1
”。AppDelegate
仅是输出行的TRUE条件。答案 1 :(得分: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
;最后print str
-打印。 (注意:您的时区和我的时区不同3小时。您的输出应会在系统上为您提供所需的结果。您还可以调整mktime
的夏令时(如果需要) ),您可以将内置的strftime
与utc-flag
配合使用以调整UTC。)
答案 2 :(得分:0)
我想读循环是最简单的。 以下:
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
将输出:
1415581203,LOGIN SUCCESS,AUTH,user2,192.168.203.63,10.146.124.73,59996,22
1415581207,LOGIN SUCCESS,AUTH,user1,172.24.31.10,172.32.1.1,48191,22
1415581211,LOGIN FAILED,AUTH,root,172.24.166.153,10.146.124.73,52506,22
答案 3 :(得分:0)
当我需要在一些历史库存数据中将日期转换为unix时间时,我遇到了同样的问题。使用了此sed
和date
命令。请注意,这仅适用于Linux(sed
和date
的GNU实现)。
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