如何优化grep

我正在尝试优化抓取/ sed的连接,因为它对于我需要的使用来说非常慢。

这是我的命令:

LANG=C tail -50 /var/log/user.log | LANG=C grep -E 'LivingLight.*STATE =' | tail -1 | cut -f2- -d= | sed -e 's/^\s*//' -e '/^$/d' | grep -E -o '([OFF|ON]*)'

想要的结果:最新的ON或OFF报告状态

此处是一些源代码行:

2019-11-11T17:04:12.757889+01:00 KitchenFan-7873 ESP-RSL: STATE = {"Time":"2019-11-11T17:04:12","Uptime":"4T20:12:27","Heap":22,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"POWER":"OFF","Wifi":{"AP":1,"SSId":"Home9785","BSSId":"10:13:31:C8:D9:D3","Channel":6,"RSSI":80,"LinkCount":61,"Downtime":"0T00:19:04"}}
2019-11-11T17:04:13.680766+01:00 4CHdoorManager ESP-RSL: STATE = {"Time":"2019-11-11T17:04:13","Uptime":"0T01:46:13","POWER1":"OFF","POWER2":"OFF","POWER3":"OFF","POWER4":"OFF","RSSI":100,"LinkCount":1,"Downtime":"0T00:00:04"}}
2019-11-11T17:04:13.681045+01:00 4CHdoorManager ESP-RSL: SENSOR = {"Time":"2019-11-11T17:04:13","AM2301":{"Temperature":null,"Humidity":null},"TempUnit":"C"}
2019-11-11T17:04:15.124453+01:00 LivingLight ESP-RSL: STATE = {"Time":"2019-11-11T17:04:14","Uptime":"4T20:12:26","Heap":21,"LinkCount":26,"Downtime":"0T00:17:20"}}
2019-11-11T17:04:18.503329+01:00 EmergencyLight ESP-RSL: STATE = {"Time":"2019-11-11T17:04:18","Uptime":"4T20:11:20","POWER":"ON","Downtime":"0T00:17:25"}}
2019-11-11T17:04:18.503783+01:00 EmergencyLight ESP-RSL: SENSOR = {"Time":"2019-11-11T17:04:18","AM2301":{"Temperature":19.9,"Humidity":48.7},"TempUnit":"C"}
2019-11-11T17:04:21.187349+01:00 BedroomBlind ESP-RSL: STATE = {"Time":"2019-11-11T17:04:21","Uptime":"4T20:11:34","RSSI":66,"LinkCount":33,"Downtime":"0T00:17:50"}}
2019-11-11T17:04:36.187722+01:00 MasterSwitch ESP-RSL: tele/sonoff/STATE = {"Time":"2019-11-11T17:04:35","Uptime":"4T20:11:41","Downtime":"0T00:17:15"}}
2019-11-11T17:04:36.197470+01:00 MasterSwitch ESP-RSL: tele/sonoff/SENSOR = {"Time":"2019-11-11T17:04:35","ENERGY":{"TotalStartTime":"2019-11-05T21:43:42","Total":24.195,"Yesterday":4.350,"Today":2.068,"Period":1,"Power":66,"ApparentPower":170,"ReactivePower":157,"Factor":0.39,"Voltage":223,"Current":0.762}}
2019-11-11T17:04:36.321760+01:00 LivingBlind ESP-RSL: tele/sonoff/STATE = {"Time":"2019-11-11T17:04:36","Uptime":"4T20:11:15","RSSI":76,"LinkCount":28,"Downtime":"0T00:17:41"}}
2019-11-11T17:04:36.542349+01:00 BathroomFan ESP-RSL: STATE = {"Time":"2019-11-11T17:04:36","Uptime":"4T06:41:33","RSSI":50,"LinkCount":32,"Downtime":"0T00:17:16"}}
2019-11-11T17:04:36.542956+01:00 BathroomFan ESP-RSL: SENSOR = {"Time":"2019-11-11T17:04:36","AM2301":{"Temperature":21.2,"Humidity":48.2},"TempUnit":"C"}
2019-11-11T17:04:37.519628+01:00 BedroomLight ESP-RSL: STATE = {"Time":"2019-11-11T17:04:38","RSSI":58,"LinkCount":38,"Downtime":"0T00:18:00"}}
2019-11-11T17:04:43.241885+01:00 BadroomAuxLeft ESP-RSL: tele/sonoff/STATE = {"Time":"2019-11-11T17:04:43","Uptime":"0T12:53:06","RSSI":44,"LinkCount":4,"Downtime":"0T00:02:04"}}
2019-11-11T17:04:43.245286+01:00 BadroomAuxLeft ESP-RSL: tele/sonoff/SENSOR = {"Time":"2019-11-11T17:04:43","TempUnit":"C"}
2019-11-11T17:04:46.721135+01:00 EntranceLight ESP-RSL: STATE = {"Time":"2019-11-11T17:04:46","Uptime":"5T09:11:18","UptimeSec":465078,"Heap":28,"MqttCount":0,"LinkCount":27,"Downtime":"0T00:19:25"}}
2019-11-11T17:04:46.787822+01:00 BadroomAuxRight ESP-RSL: tele/sonoff/STATE = {"Time":"2019-11-11T17:04:46","Uptime":"4T20:10:09","RSSI":56,"Downtime":"0T00:16:53"}}
2019-11-11T17:04:59.495380+01:00 GuestRoomLight ESP-RSL: STATE = {"Time":"2019-11-11T17:05:00","Uptime":"4T20:12:22","LinkCount":34,"Downtime":"0T00:17:40"}}

预先感谢您的支持。

已经放LANG = C可以改善执行时间,但还不够。

lihuizi0806 回答:如何优化grep

tac的良好实现应使用fseek(... SEEK_END)。与grep -m1混合使用时,应该可以从结尾到第一个匹配的字符串快速解析文件。使用grep -P,我们可以删除所有不需要的解析和处理-我们可以在OFF/ON中提取grep

tac /var/log/user.log | grep -m1 -o -P 'LivingLight.*STATE =.*"POWER":"\K[^"]*'
,

在awk中使用默认的字段分隔符(空格,制表符):

$ awk '                                 # using awk,$2=="LivingLight" {                     # if second field is LivingLight
    b=$NF                               # buffer last field
}
END {                                   # in the end
    if(match(b,/(ON|OFF)/))             # look for ON/OFF in last buffered entry
        print substr(b,RSTART,RLENGTH)  # output if found
}' file

这次输出:

OFF

tail可以更快地使用。一线:

$ awk '$2=="LivingLight"{b=$NF}END{if(match(b,/(ON|OFF)/))print substr(b,RLENGTH)}' file

或在另一个答案中建议使用tac

$ tac file | awk '
$2=="LivingLight" {                       # if match
    if(match($NF,/(ON|OFF)/)) {           # find ON/OFF
        print substr($NF,RLENGTH)  # output
        exit                              # and exit
    }
}' 

单线:

$ tac file | awk '$2=="LivingLight"{if(match($NF,/(ON|OFF)/)){print substr($NF,RLENGTH);exit}}'
本文链接:https://www.f2er.com/3122885.html

大家都在问