简体   繁体   English

我如何使用bash将日期和时间格式更改为yyyy-mm-dd hh:mm:ss,这是来自apache日志文件

[英]How can I change this date and time format to yyyy-mm-dd hh:mm:ss using bash, this is from an apache log file

49,10.96.25.156,1274x40x1,-,02/Nov/2017:21:14:31,http-nio-443-exec-20,"POST/rest/webResources/1.0/resourcesHTTP/1.1",503,40,0,"-","SilkPerformer17.0""-"
50,10.96.25.156,1274x41x1,-,02/Nov/2017:21:14:31,http-nio-443-exec-25,"POST/rest/webResources/1.0/resourcesHTTP/1.1",503,40,0,"-","SilkPerformer17.0""9myyx9"

This is how the log file looks, any help would be appreciated. 这是日志文件的外观,任何帮助将不胜感激。 Thanks! 谢谢!

You can use either date or awk to do the conversion. 您可以使用dateawk进行转换。 If you have the dateutils package installed, here is a straightforward command that you can use 如果您安装了dateutils软件包,则可以使用以下简单命令

dateutils.dconv -S -i "%d/%b/%Y:" -f "%F " < file.log
  • -i to specify input date format -i指定输入日期格式
  • -f to specify output date format -f指定输出日期格式
  • -S sed mode, to process only the matched date string -S sed模式,仅处理匹配的日期字符串

Input 输入项

49,10.96.25.156,1274x40x1,-,02/Nov/2017:21:14:31,http-nio-443-exec-20

Output 输出量

49,10.96.25.156,1274x40x1,-,2017-11-02 21:14:31,http-nio-443-exec-20

Here's a pure awk solution: 这是一个纯awk解决方案:

#!/usr/bin/env awk -f

BEGIN {
  FS = OFS = ","

  # build our lookup of zero-padded month numbers
  split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec", marr, "|")
  for (i = 1; i <= 12; i++) {
    mhash[marr[i]] = sprintf("%02d", i)
  }
}

{
  # 1:dd 2:mmm 3:yyyy 4:hh 5:mi 6:ss
  split($5, dtarr, "[:/]")

  # replace the column with our reformatted date
  $5 = dtarr[3] "-" mhash[dtarr[2]] "-" dtarr[1] " " dtarr[4] ":" dtarr[5] ":" dtarr[6]

  # print the whole line
  print
}

To use it: 要使用它:

$ awk -f redate.awk access_log
49,10.96.25.156,1274x40x1,-,2017-11-02 21:14:31,http-nio-443-exec-20,"POST/rest/webResources/1.0/resourcesHTTP/1.1",503,40,0,"-","SilkPerformer17.0""-"

Or you can make it executable: 或者您可以使其可执行:

$ chmod +x redate.awk

And run it directly: 并直接运行它:

$ ./redate.awk access_log
49,10.96.25.156,1274x40x1,-,2017-11-02 21:14:31,http-nio-443-exec-20,"POST/rest/webResources/1.0/resourcesHTTP/1.1",503,40,0,"-","SilkPerformer17.0""-"

bash only conversion: 仅限bash转换:

declare -A m
m=([Jan]=01 [Feb]=02 [Mar]=03 [Apr]=04 [May]=05 [Jun]=06 [Jul]=07 [Aug]=08 [Set]=09 [Oct]=10 [Nov]=11 [Dec]=12)
IFS='/:' read -r -a a <<< '02/Nov/2017:21:14:31'
echo "${a[2]}-${m[${a[1]}]}-${a[0]} ${a[3]}:${a[4]}:${a[5]}"

EDIT 编辑

I mean something like this to read the file and split the lines 我的意思是这样的事情来读取文件并拆分行

printline() {
    local l=("$@")
    echo -n "${l[0]}"
    for f in "${l[@]:1}"
    do
        echo -n ",$f"
    done
    echo
}

declare -A m
m=([Jan]=01 [Feb]=02 [Mar]=03 [Apr]=04 [May]=05 [Jun]=06 [Jul]=07 [Aug]=08 [Set]=09 [Oct]=10 [Nov]=11 [Dec]=12)
while read line
do
    IFS=',' read -r -a l <<< "$line"
    IFS='/:' read -r -a a <<< ${l[4]}
    l[4]="${a[2]}-${m[${a[1]}]}-${a[0]} ${a[3]}:${a[4]}:${a[5]}"
    printline "${l[@]}"
done

using date for converting could be like this 使用日期进行转换可能像这样

IFS=,
while read a b c d dat remaining
do
    dat=${dat//\// }  # remove all / from date-field
    dat=${dat/:/ }    # remove first : from date-field
    echo "$a,$b,$c,$d,$(date --date="$dat" "+%Y-%m-%d %H:%M:%S"),$remaining"
done < redate.dat

First we have change the date-field, into something date is able to understand. 首先,我们将日期字段更改为可以理解的日期。 Then we choose the output format as needed. 然后,根据需要选择输出格式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM