Linux shell:检测CSV日志文件上的状态更改
这是我自动生成的日志文件(连续一分钟检查我的互联网线路): 我试图通过编写一些解释方法,使其更易于阅读,这些解释方法取决于第三个字段(行状态:OK/ERROR)状态,删除连续的值,某种外壳脚本,只显示互联网行的初始和状态更改,将上述日志转换为:Linux shell:检测CSV日志文件上的状态更改,csv,logging,Csv,Logging,这是我自动生成的日志文件(连续一分钟检查我的互联网线路): 我试图通过编写一些解释方法,使其更易于阅读,这些解释方法取决于第三个字段(行状态:OK/ERROR)状态,删除连续的值,某种外壳脚本,只显示互联网行的初始和状态更改,将上述日志转换为: 2018-04-27,23:37,OK 2018-04-27,23:40,ERROR 2018-04-27,23:42,OK 这意味着: 2018-04-27,23:37,Entered Status OK 2018-04-27,23:40,Enter
2018-04-27,23:37,OK
2018-04-27,23:40,ERROR
2018-04-27,23:42,OK
这意味着:
2018-04-27,23:37,Entered Status OK
2018-04-27,23:40,Entered Status ERROR
2018-04-27,23:42,Entered Status OK
可以看出,只保留状态更改会使日志显示更短,更易于阅读
假设日志文件可能很长(考虑数月的一分钟日志记录),在Linux shell上编写此“解释”脚本的合适(有效)方法是什么
我知道在shell上迭代不是一个很好的主意,所以我考虑了AWK
,但我对它不是很有经验。当然,循环解决方案总比没有好 进一步数据:
- 一个类似的(但不是相同的)问题(我也问过)
- AWK方法:
awk -F "," '$3==last{next} {last=$3} {print $0}' log.csv
这将产生:
2018-04-27,23:37,OK
2018-04-27,23:40,ERROR
2018-04-27,23:42,OK
它的工作原理:
用于逗号作为字段分隔符-F“,”
忽略第三个字段等于$3==last{next}
变量的任何行:命令last
告诉awk跳过所有剩余的命令并在下一行重新开始next
保存变量last中的第三个字段(确定/错误)last=$3
表示打印当前行{print$0}
选项1。Bash
uniq
当日志行开始长度相同或字段之间的分隔符为空格或制表符时,命令就足够了
uniq -s 17 log.csv
uniq
过滤掉相邻的匹配行,而-s17
标志使其忽略构成时间戳的每行的前17个字符
uniq -f 2 log.csv
-f2使uniq
忽略前两个字段。不幸的是,无法将默认分隔符从空白更改为其他内容
选项2。tr
和uniq
将适用于可以轻松切换分隔符的简单情况
# tab is inserted with CTRL+V followed by TAB
tr ',' ' ' < log.csv | uniq -f 2
sed
是stream editor的缩写,它将用制表符替换逗号的前两次出现(sed
允许使用\t)sed's/,/\t/'log.csv
将只替换第一次出现的内容,因此通过添加相同的搜索和替换模式两次(以分号分隔),重复相同的搜索两次
了解有关uniq使用的更多信息:
man uniq
uniq --help
我不知道uniq的那种能力。顺便说一句,提议的示例是一个简化的示例,因此
17
偏移量可能会改变(即:对于CSV文件上的非固定宽度字段),这将需要更多的解析/编程。尽管如此,这仍然是一个很好的可能性,因为据我所知,uniq
命令是一个快速(对大文件有效)的工具。谢谢你。
sed 's/,/\t/;s/,/\t/' log.csv | uniq -f 2
man uniq
uniq --help