代码之家  ›  专栏  ›  技术社区  ›  NanoTech

在bash-awk命令中格式化日期

  •  0
  • NanoTech  · 技术社区  · 11 月前

    我试图以某种格式获取一些日志的日期,以便以后进行比较,这是我的命令:

    fgrep "<expression>" <logFile> | sort | awk -F "[][]" 'messageDate=$(date -d "$2" "+%Y.%j.%H.%M.%S") { print messageDate }'
    

    我打印的是日志文件的整行。

    如果我运行以下命令:

    fgrep "<expression>" <logFiles> | sort | awk -F "[][]" 'messageDate=$(date -d "$2" "+%Y.%j.%H.%M.%S") { print $2 }'
    

    我得到了日期,但不是我想要的格式。

    2014-09-04T08:22:16Z
    2017-10-08T16:05:06Z
    2022-11-30T14:50:16Z
    

    日志文件包含以下消息:

    [2022-11-30T14:50:16Z] <Info/Warning/Error>: <log message>
    

    有人理解awk工作的原因吗?这意味着它正确地分割了文件,但代码 messageDate=$(date -d "$2" "+%Y.%j.%H.%M.%S") 不知怎么的,又收到完整的日志消息了吗?

    2 回复  |  直到 11 月前
        1
  •  3
  •   Ed Morton    11 月前

    关于“bash-awk命令”,bash和awk是两个完全不同的工具。你可以从bash调用awk,也可以从awk调用bash,就像你可以从bash调用C程序或perl脚本一样,反之亦然,但每个工具都有自己独立的语言、作用域等。

    当你写道:

    awk -F "[][]" '
        messageDate=$(date -d "$2" "+%Y.%j.%H.%M.%S") {
            print messageDate
        }
    '
    

    您正试图在awk脚本中使用bash语法,这比在C程序中使用bash句法更不可能奏效。

    调用Unix实用程序,如 date awk (通过中间外壳,如 bash )并将结果存储在awk变量中,如果操作成功,则打印结果,就像您在脚本中试图做的那样,可以使用任何awk:

    awk -F "[][]" '
        {
            messageDate = ""
            if ( ("date -d \047" $2 "\047 \047+%Y.%j.%H.%M.%S\047" | getline line) > 0 ) {
                messageDate = line
            }
        }
        messageDate != "" { print messageDate }
    '
    

    请参阅 http://awk.freeshell.org/AllAboutGetline (或者,如果它下降了, https://web.archive.org/web/20221109201352/http://awk.freeshell.org/AllAboutGetline )有关我如何使用的更多信息 getline 在那里。

    不过,如果你使用的是GNU awk,它有自己的内置 time functions 所以你可以这样做:

    awk -F "[][]" '
        {
            messageDate = ""
            secs = mktime( gensub(/[-T:Z]/, " ", "g", $2), 1 )
            if ( secs >= 0 ) {
                messageDate = strftime("%Y.%j.%H.%M.%S", secs)
            }
        }
        messageDate != "" { print messageDate }
    ' file
    

    这将比awk生成一个shell来调用快几个数量级 日期 每条输入线一次。

        2
  •  2
  •   anubhava    11 月前

    您可以尝试以下解决方案:

    awk -F '[][]' '/expression/ {print $2}' logFile | 
    date "+%Y.%j.%H.%M.%S" -f - |
    sort -n
    

    请注意,您不需要 grep 自从 awk 也可以在找到文本时仅打印这些列 expression 排成一行。