如何使用grep查找损坏的NMEA日志句子?
时间:2020-03-05 18:45:38 来源:igfitidea点击:
我的GPS记录器有时在日志文件的末尾留下"未完成"行。我认为它们只是在末尾,但我想检查所有行以防万一。
一个完整的例句示例如下:
$GPRMC,005727.000,A,3751.9418,S,14502.2569,E,0.00,339.17,210808,,,A*76
该行应以" $"符号开头,并以" *"和两个字符的十六进制校验和结尾。我不在乎校验和是否正确,只要它存在即可。它还需要忽略没有校验和且位于每个文件开头的" ADVER"语句。
以下Python代码可能有效:
import re from path import path nmea = re.compile("^$.+\*[0-9A-F]{2}$") for log in path("gpslogs").files("*.log"): for line in log.lines(): if not nmea.match(line) and not "ADVER" in line: print "%s\n\t%s\n" % (log, line)
有没有办法用grep或者awk或者简单的方法做到这一点?我还没有真正想出如何让grep
来做我想做的事情。
更新:感谢@Motti和@Paul,我能够获得以下内容来完成几乎我想做的事情,但是必须使用单引号并删除尾部的$才起作用:
grep -nvE '^$.*\*[0-9A-F]{2}' *.log | grep -v ADVER | grep -v ADPMB
出现另外两个问题,如何使它忽略空白行?我可以合并后两个grep
s吗?
解决方案
回答
最少的测试表明应该这样做:
grep -Ev "^$.*\*[0-9A-Fa-f]{2}$" a.txt | grep -v ADVER
- -E使用扩展的正则表达式
- -v显示不匹配的行
- ^开头为
- 。* 任何事物
- \ *星号
- [0-9A-Fa-f]十六进制数字
- {2}恰好是前两个
- $行尾
- |
grep -v ADVER
清除ADVER行
HTH,Motti。
回答
@Motti的答案不会忽略ADVER行,但是我们可以轻松地将该grep的结果传递给另一个:
grep -Ev "^$.*\*[0-9A-Fa-f]{2}$" a.txt |grep -v ADVER
回答
@Tom (rephrased) I had to remove the trailing $ for it to work
删除$表示该行可能以其他结尾(例如,将接受以下内容)
$GPRMC,005727.000,A,3751.9418,S,14502.2569,E,0.00,339.17,210808,,,A*76xxx
@Tom And can I combine the last two greps?
grep -Ev "ADVER|ADPMB"
回答
@Motti:组合grep不起作用,没有效果。
我知道没有尾随的$校验和仍然可以匹配其他东西,但是它根本不起作用,所以我别无选择。
GNU grep 2.5.3和GNU bash 3.2.39(1)是否有任何区别。
而且看起来日志文件正在使用DOS换行符(CR + LF)。 grep
是否需要一个开关来正确处理?
回答
汤姆
GNU grep 2.5.3 and GNU bash 3.2.39(1) if that makes any difference. And it looks like the log files are using DOS line-breaks (CR+LF). Does grep need a switch to handle that properly?
我在Windows上使用grep(GNU grep)2.4.2
(真可惜!),它对我有用(并且DOS换行符自然被接受),目前我真的没有访问其他操作系统的权限。所以很抱歉,但我将无法为我们提供进一步的帮助:o(