如何在awk中选择日期范围

如何在awk中选择日期范围,awk,grep,cat,Awk,Grep,Cat,我们正在制作一个实用程序,用于将ssh连接到不同的服务器,收集所有错误日志并发送给相关团队。该实用程序将使用awk对日志文件进行分类和筛选。e、 g cat/app1/apache/tomcat7/logs/catalina.out | awk'$0>=from&&$0从技术上讲,您可以从awk调用date,但这种方法的帮助有限: 从awk调用日期(或其他程序)代价高昂(启动进程等)。如果日志文件很大,处理速度会很慢 看起来您正在寻找可以在远程服务器上执行的“一行程序”。处理多种格式将需要多个

我们正在制作一个实用程序,用于将ssh连接到不同的服务器,收集所有错误日志并发送给相关团队。该实用程序将使用awk对日志文件进行分类和筛选。e、 g


cat/app1/apache/tomcat7/logs/catalina.out | awk'$0>=from&&$0从技术上讲,您可以从awk调用
date
,但这种方法的帮助有限:

  • awk
    调用日期(或其他程序)代价高昂(启动进程等)。如果日志文件很大,处理速度会很慢
  • 看起来您正在寻找可以在远程服务器上执行的“一行程序”。处理多种格式将需要多个行程序
考虑解除这些约束-以下一项(或多项):

  • 将完整的日志文件传输到能够在本地运行筛选器的机器上,支持多个日期
  • 发送更复杂的脚本以在每个远程服务器上执行扫描。这将需要稍多的设置,但不需要通过ssh传输完整的日志文件
  • 自定义日志文件-catalina、Apache等,允许您控制日期格式。使所有这些产品生产出
    YYYY-MM-DD HH:MM
    ,或类似产品

从技术上讲,您可以从awk调用
date
,但这种方法的帮助有限:

  • awk
    调用日期(或其他程序)代价高昂(启动进程等)。如果日志文件很大,处理速度会很慢
  • 看起来您正在寻找可以在远程服务器上执行的“一行程序”。处理多种格式将需要多个行程序
考虑解除这些约束-以下一项(或多项):

  • 将完整的日志文件传输到能够在本地运行筛选器的机器上,支持多个日期
  • 发送更复杂的脚本以在每个远程服务器上执行扫描。这将需要稍多的设置,但不需要通过ssh传输完整的日志文件
  • 自定义日志文件-catalina、Apache等,允许您控制日期格式。使所有这些产品生产出
    YYYY-MM-DD HH:MM
    ,或类似产品

  • 答案是awk对日期一无所知。Awk知道数字和字符串,并且只能比较它们。因此,当您想要选择日期和时间时,您必须确保您比较的日期格式是可排序的,并且有多种格式:

    | type       | example                   | sortable |
    |------------+---------------------------+----------|
    | ISO-8601   | 2019-11-19T10:05:15       | string   |
    | RFC-2822   | Tue, 19 Nov 2019 10:05:15 | not      |
    | RFC-3339   | 2019-11-19 10:05:15       | string   |
    | Unix epoch | 1574157915                | numeric  |
    | AM/PM      | 2019-11-19 10:05:15 am    | not      |
    | MM/DD/YYYY | 11/19/2019 10:05:15       | not      |
    | DD/MM/YYYY | 19/11/2019 10:05:15       | not      |
    
    因此,您必须将不可排序的格式转换为可排序的格式,主要使用字符串操作。实现您想要的目标的模板awk程序如下所示:

    # function to convert a string into a sortable format
    function convert_date(str) {
        return sortable_date
    }
    # function to extract the date from the record
    function extract_date(str) {
        return extracted_date
    }
    # convert the range
    (FNR==1) { t1 = convert_date(begin); t2 = convert_date(end) }
    # extract the date from the record
    { date_string = extract_date($0) }
    # convert the date of the record
    { t = convert_date(date_string) }
    # make the selection
    (t1 <= t && t < t2) { print }
    
    注意:以上假设为单行日志条目。只需稍作调整,就可以处理多行日志条目


    在原始问题中,提供了以下格式:

    EEE MMM dd yy HH:mm         # not sortable
    EEE MMM dd HH:mm            # not sortable
    yyyy-MM-dd hh:mm            # sortable
    dd MMM yyyy HH:mm:ss        # not sortable
    
    从上面可以看出,除了第二种格式之外,其他格式都可以轻松地转换为可排序格式。第二种格式错过了我们必须利用一周中的某一天进行详细检查的年份。这是非常困难的,而且永远不会100%防弹

    除第二种格式外,我们可以编写以下函数:

    BEGIN {
        datefmt1="^[a-Z][a-Z][a-Z] [a-Z][a-Z][a-Z] [0-9][0-9] [0-9][0-9] [0-9][0-9]:[0-9][0-9]"
        datefmt3="^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]"
        datefmt4="^[0-9][0-9] [a-Z][a-Z][a-Z] [0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]"
    }
    # convert the range
    (FNR==1) { t1 = convert_date(begin); t2 = convert_date(end) }
    # extract the date from the record
    { date_string = extract_date($0) }
    # skip if date string is empty
    (date_string == "") { next }
    # convert the date of the record
    { t = convert_date(date_string) }
    # make the selection
    (t1 <= t && t < t2) { print }
    
    # function to extract the date from the record
    function extract_date(str,    date_string) {
        date_string=""
        if (match(datefmt1,str)) { date_string=substr(str,RSTART,RLENGTH) }
        else if (match(datefmt3,str)) { date_string=substr(str,RSTART,RLENGTH) }
        else if (match(datefmt4,str)) { date_string=substr(str,RSTART,RLENGTH) }
        return date_string
    }
    # function to convert a string into a sortable format
    # converts it in the format YYYYMMDDhhmmss
    function convert_date(str, a,fmt, YYYY,MM,DD,T, sortable_date) {
        sortable_date=""
        if (match(datefmt1,str)) { 
            split(str,a,"[ ]")
            YYYY=(a[4] < 70 ? "19" : "20")a[4]
            MM=get_month(a[2]); DD=a[3]
            T=a[5]; gsub(/[^0-9]/,T)"00"
            sortable_date = YYYY MM DD T
        }
        else if (match(datefmt3,str)) { 
            sortable_date = str"00"
            gsub(/[^0-9]/,sortable_date)
        }
        else if (match(datefmt4,str)) { 
            split(str,a,"[ ]")
            YYYY=a[3]
            MM=get_month(a[2]); DD=a[1]
            T=a[4]; gsub(/[^0-9]/,T)"00"
            sortable_date = YYYY MM DD T
        }
        return sortable_date
    }
    # function to convert Jan->01, Feb->02, Mar->03 ... Dec->12
    function get_month(str) {
       return sprintf("%02d",(match("JanFebMarAprMayJunJulAugSepOctNovDec",str)+2)/3)
    }
    
    开始{
    datefmt1=“^[a-Z][a-Z][a-Z][a-Z][a-Z][0-9][0-9][0-9][0-9][0-9][0-9][0-9]:[0-9][0-9]”
    datefmt3=“^[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9]:[0-9][0-9]”
    datefmt4=“^[0-9][0-9][a-Z][a-Z][a-Z][0-9][0-9][0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9]:[0-9][0-9]。”
    }
    #转换范围
    (FNR==1){t1=转换日期(开始);t2=转换日期(结束)}
    #从记录中提取日期
    {date\u string=extract\u date($0)}
    #如果日期字符串为空,则跳过
    (日期字符串==“”){next}
    #转换记录的日期
    {t=转换日期(日期字符串)}
    #选择
    (t1 01年2月->02年3月->03…12月->12日
    函数get_月(str){
    返回sprintf(“%02d”)(匹配(“Janfebmarapmayjunjunaugsepoctnovdec”,str)+2)/3)
    }
    

    答案是,awk不知道日期是什么。awk知道数字和字符串,只能比较它们。因此,当您想要选择日期和时间时,您必须确保您比较的日期格式是可排序的,并且有多种格式:

    | type       | example                   | sortable |
    |------------+---------------------------+----------|
    | ISO-8601   | 2019-11-19T10:05:15       | string   |
    | RFC-2822   | Tue, 19 Nov 2019 10:05:15 | not      |
    | RFC-3339   | 2019-11-19 10:05:15       | string   |
    | Unix epoch | 1574157915                | numeric  |
    | AM/PM      | 2019-11-19 10:05:15 am    | not      |
    | MM/DD/YYYY | 11/19/2019 10:05:15       | not      |
    | DD/MM/YYYY | 19/11/2019 10:05:15       | not      |
    
    因此,您必须将非可排序格式转换为可排序格式,主要使用字符串操作。实现所需功能的模板awk程序如下所示:

    # function to convert a string into a sortable format
    function convert_date(str) {
        return sortable_date
    }
    # function to extract the date from the record
    function extract_date(str) {
        return extracted_date
    }
    # convert the range
    (FNR==1) { t1 = convert_date(begin); t2 = convert_date(end) }
    # extract the date from the record
    { date_string = extract_date($0) }
    # convert the date of the record
    { t = convert_date(date_string) }
    # make the selection
    (t1 <= t && t < t2) { print }
    
    注意:以上假设为单行日志条目。只需稍加修改,即可处理多行日志条目


    在原始问题中,提供了以下格式:

    EEE MMM dd yy HH:mm         # not sortable
    EEE MMM dd HH:mm            # not sortable
    yyyy-MM-dd hh:mm            # sortable
    dd MMM yyyy HH:mm:ss        # not sortable
    
    综上所述,除了第二种格式外,其他格式都可以轻松转换为可排序格式。第二种格式错过了我们必须利用一周中的某一天进行详细检查的年份。这是非常困难的,而且永远不会100%防弹

    除第二种格式外,我们可以编写以下函数:

    BEGIN {
        datefmt1="^[a-Z][a-Z][a-Z] [a-Z][a-Z][a-Z] [0-9][0-9] [0-9][0-9] [0-9][0-9]:[0-9][0-9]"
        datefmt3="^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]"
        datefmt4="^[0-9][0-9] [a-Z][a-Z][a-Z] [0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]"
    }
    # convert the range
    (FNR==1) { t1 = convert_date(begin); t2 = convert_date(end) }
    # extract the date from the record
    { date_string = extract_date($0) }
    # skip if date string is empty
    (date_string == "") { next }
    # convert the date of the record
    { t = convert_date(date_string) }
    # make the selection
    (t1 <= t && t < t2) { print }
    
    # function to extract the date from the record
    function extract_date(str,    date_string) {
        date_string=""
        if (match(datefmt1,str)) { date_string=substr(str,RSTART,RLENGTH) }
        else if (match(datefmt3,str)) { date_string=substr(str,RSTART,RLENGTH) }
        else if (match(datefmt4,str)) { date_string=substr(str,RSTART,RLENGTH) }
        return date_string
    }
    # function to convert a string into a sortable format
    # converts it in the format YYYYMMDDhhmmss
    function convert_date(str, a,fmt, YYYY,MM,DD,T, sortable_date) {
        sortable_date=""
        if (match(datefmt1,str)) { 
            split(str,a,"[ ]")
            YYYY=(a[4] < 70 ? "19" : "20")a[4]
            MM=get_month(a[2]); DD=a[3]
            T=a[5]; gsub(/[^0-9]/,T)"00"
            sortable_date = YYYY MM DD T
        }
        else if (match(datefmt3,str)) { 
            sortable_date = str"00"
            gsub(/[^0-9]/,sortable_date)
        }
        else if (match(datefmt4,str)) { 
            split(str,a,"[ ]")
            YYYY=a[3]
            MM=get_month(a[2]); DD=a[1]
            T=a[4]; gsub(/[^0-9]/,T)"00"
            sortable_date = YYYY MM DD T
        }
        return sortable_date
    }
    # function to convert Jan->01, Feb->02, Mar->03 ... Dec->12
    function get_month(str) {
       return sprintf("%02d",(match("JanFebMarAprMayJunJulAugSepOctNovDec",str)+2)/3)
    }
    
    开始{
    datefmt1=“^[a-Z][a-Z][a-Z][a-Z][a-Z][0-9][0-9][0-9][0-9][0-9][0-9][0-9]:[0-9][0-9]”
    datefmt3=“^[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9]:[0-9][0-9]”
    datefmt4=“^[0-9][0-9][a-Z][a-Z][a-Z][0-9][0-9][0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9]:[0-9][0-9]。”
    }
    #转换范围
    (FNR==1){t1=转换日期(开始);t2=转换日期(结束)}
    #从记录中提取日期
    {date\u string=extract\u date($0)}
    #如果日期字符串为空,则跳过
    (日期字符串==“”){next}
    #转换记录的日期
    {t=转换日期(日期字符串)}
    #选择
    (t1 01年2月->02年3月->03…12月->12日
    函数get_月(str){
    返回sprintf(“%02d”)(匹配(“Janfebmarapmayjunjunaugsepoctnovdec”,str)+2)/3)
    }
    

    请在您的问题中发布输入和预期输出的样本。评论不用于发布样本或代码,pl
    BEGIN {
        datefmt1="^[a-Z][a-Z][a-Z] [a-Z][a-Z][a-Z] [0-9][0-9] [0-9][0-9] [0-9][0-9]:[0-9][0-9]"
        datefmt3="^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]"
        datefmt4="^[0-9][0-9] [a-Z][a-Z][a-Z] [0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]"
    }
    # convert the range
    (FNR==1) { t1 = convert_date(begin); t2 = convert_date(end) }
    # extract the date from the record
    { date_string = extract_date($0) }
    # skip if date string is empty
    (date_string == "") { next }
    # convert the date of the record
    { t = convert_date(date_string) }
    # make the selection
    (t1 <= t && t < t2) { print }
    
    # function to extract the date from the record
    function extract_date(str,    date_string) {
        date_string=""
        if (match(datefmt1,str)) { date_string=substr(str,RSTART,RLENGTH) }
        else if (match(datefmt3,str)) { date_string=substr(str,RSTART,RLENGTH) }
        else if (match(datefmt4,str)) { date_string=substr(str,RSTART,RLENGTH) }
        return date_string
    }
    # function to convert a string into a sortable format
    # converts it in the format YYYYMMDDhhmmss
    function convert_date(str, a,fmt, YYYY,MM,DD,T, sortable_date) {
        sortable_date=""
        if (match(datefmt1,str)) { 
            split(str,a,"[ ]")
            YYYY=(a[4] < 70 ? "19" : "20")a[4]
            MM=get_month(a[2]); DD=a[3]
            T=a[5]; gsub(/[^0-9]/,T)"00"
            sortable_date = YYYY MM DD T
        }
        else if (match(datefmt3,str)) { 
            sortable_date = str"00"
            gsub(/[^0-9]/,sortable_date)
        }
        else if (match(datefmt4,str)) { 
            split(str,a,"[ ]")
            YYYY=a[3]
            MM=get_month(a[2]); DD=a[1]
            T=a[4]; gsub(/[^0-9]/,T)"00"
            sortable_date = YYYY MM DD T
        }
        return sortable_date
    }
    # function to convert Jan->01, Feb->02, Mar->03 ... Dec->12
    function get_month(str) {
       return sprintf("%02d",(match("JanFebMarAprMayJunJulAugSepOctNovDec",str)+2)/3)
    }