答案是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 }
在大多数情况下,可以大大减少此程序。如果以上内容存储在extract_date_range.awk
中,则可以将其运行为:
$ awk -f extract_date_range.awk begin="date-in-know-format" end="date-in-known-format" logfile
注意:以上假设单行登录。稍作改动,您就可以处理多行日志条目。
在原始问题中,提出了以下格式:
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
从以上所述,除第二种格式外,其他所有格式都可以轻松转换为可排序格式。第二种格式错过了Year,因此我们必须利用星期几来进行详尽的检查。这是极其困难的,而且永远不会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,RLENGTH) }
else if (match(datefmt4,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,"[ ]")
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,"[ ]")
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)
}
,
从技术上讲,您可以从awk调用date
,但是这种方法的帮助有限:
- 从
awk
调用日期(或其他程序)非常昂贵(启动进程等)。如果日志文件很大,处理将会很慢
- 看起来您正在寻找可以在远程服务器上执行的“单一代码”。处理多种格式将需要多种格式。
考虑解除这些限制-以下一项(或多项):
- 将完整的日志文件传输到能够在本地运行过滤器并支持多个日期的计算机。
- 发送更复杂的脚本以在每个远程服务器上执行扫描。这将需要更多的设置,但是将不需要通过ssh传输完整的日志文件。
- 自定义日志文件-catalina,Apache等,可让您控制日期格式。使它们全部产生
YYYY-MM-DD HH:MM
或类似的结果。
本文链接:https://www.f2er.com/3076628.html