Linux shell:检测CSV日志文件上的状态更改

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

这是我自动生成的日志文件(连续一分钟检查我的互联网线路):

我试图通过编写一些解释方法,使其更易于阅读,这些解释方法取决于第三个字段(行状态: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,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
        变量的任何行:命令
        next
        告诉awk跳过所有剩余的命令并在下一行重新开始
      • last=$3
        保存变量last中的第三个字段(确定/错误)
      • {print$0}
        表示打印当前行
      对于任何特殊情况都不是完美的解决方案,例如:如果第三个字段为空。但这对我来说已经足够了

      多亏了John1024的帮助


      选项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