chlryg 发表于 2024-3-26 21:25

请教一下Linux命令grep -P参数与正则表达式的过滤语法

Ctgzalk@Ubuntu:~$ cat -n log_2024-03-26_143126.csv
   12024-03-26 15:09,B列数值,C列数值,D列数值,14.18,F列数值,24,H列数值,I列数值
   22024-03-26 15:09,B列数值,C列数值,D列数值,5,F列数值,34,H列数值,I列数值
   32024-03-26 15:09,B列数值,C列数值,D列数值,9,F列数值,35,H列数值,I列数值
   42024-03-26 15:09,B列数值,C列数值,D列数值,2,F列数值,30,H列数值,I列数值
   52024-03-26 15:09,B列数值,C列数值,D列数值,3,F列数值,24,H列数值,I列数值
   62024-03-26 15:09,B列数值,C列数值,D列数值,5,F列数值,24,H列数值,I列数值
   72024-03-26 15:09,B列数值,C列数值,D列数值,5.01,F列数值,24,H列数值,I列数值
   82024-03-26 15:09,B列数值,C列数值,D列数值,6,F列数值,24,H列数值,I列数值
   92024-03-26 15:09,B列数值,C列数值,D列数值,0,F列数值,24,H列数值,I列数值
    102024-03-26 15:09,B列数值,C列数值,D列数值,205.01,F列数值,24,H列数值,I列数值
    112024-03-26 15:09,B列数值,C列数值,D列数值,1,F列数值,24,H列数值,I列数值
    122024-03-26 15:09,B列数值,C列数值,D列数值,1,F列数值,24,H列数值,I列数值
    132024-03-26 15:09,B列数值,C列数值,D列数值,5.001,F列数值,24,H列数值,I列数值
    142024-03-26 15:09,B列数值,C列数值,D列数值,5.01,F列数值,24,H列数值,I列数值
    152024-03-26 15:09,B列数值,C列数值,D列数值,5.1,F列数值,35,H列数值,I列数值
    162024-03-26 15:09,B列数值,C列数值,D列数值,3,F列数值,40,H列数值,I列数值
    172024-03-26 15:09,B列数值,C列数值,D列数值,10,F列数值,38,H列数值,I列数值
    182024-03-26 15:09,B列数值,C列数值,D列数值,11.2,F列数值,0,H列数值,I列数值
Ctgzalk@Ubuntu:~$
Ctgzalk@Ubuntu:~$ head log_2024-03-26_144157.csv log_2024-03-26_152741.csv
==> log_2024-03-26_144157.csv <==
2024-03-26 15:09,B列数值,C列数值,D列数值,4,F列数值,24,H列数值,I列数值
2024-03-26 15:09,B列数值,C列数值,D列数值,4.01,F列数值,24,H列数值,I列数值
2024-03-26 15:09,B列数值,C列数值,D列数值,1.00,F列数值,35,H列数值,I列数值
2024-03-26 15:09,B列数值,C列数值,D列数值,11.2,F列数值,43,H列数值,I列数值

==> log_2024-03-26_152741.csv <==
2024-03-26 15:09,B列数值,C列数值,D列数值,10,F列数值,24,H列数值,I列数值
2024-03-26 15:09,B列数值,C列数值,D列数值,10.0,F列数值,24,H列数值,I列数值
2024-03-26 15:09,B列数值,C列数值,D列数值,6.01,F列数值,30,H列数值,I列数值
Ctgzalk@Ubuntu:~$
如下图所示,Linux系统的某目录下有多个.csv文件,我需要从这些csv文件中过滤出异常的行(异常的判定条件是csv的第五列出现连续三行大于5的值或者第七行出现连续三行大于32的值),若出现异常的行则需要将这三行(或三行以上的文本)>>到一个.log文件里
正则表达式琢磨了一下午也没写明白,因为第五列和第七列会出现5.0/5.001/5.1,32.0/32.0000001/32.065562这种数值,导致正则的逻辑匹配到了错误的数值,所以来请教一下各位
https://s21.ax1x.com/2024/03/26/pF5hBIf.png
https://s21.ax1x.com/2024/03/26/pF5h4oV.png
https://s21.ax1x.com/2024/03/26/pF5hgMj.png
像是5.0000是不大于5的,5.000001是大于5的
如awk命令查询的结果为例说明,按照预期的判断逻辑,上面的三个csv文件只有143126的csv的第13、14、15行(第五列值),第15、16、17行(第七列值)以及152741csv的1、2、3行(第五列值)这三处是符合匹配条件;像是144157csv文件第4行的第五列值11.2与下方的10/10.0不能算作符合匹配条件,因为这三行数值分别属于两个csv文件

LittiePang 发表于 2024-3-26 21:25

提供个菜鸡的正则思路,希望不要嫌弃:lol,我用的比较简答粗暴的方式,如果不行的话希望大佬帮我指正一下,我假设匹配在边界,如果前面有固定的格式比如,比如空白符可以替换一下E:\work\解答.jpg

chlryg 发表于 2024-3-26 21:28

正则配合grep命令支持这样的判断逻辑吗?先去csv里判定数值范围,把满足条件的行拿出来再判断是否是同一文件里连续三行出现了符合条件的数值

Andrea 发表于 2024-3-26 21:51

本身处理浮点数就不友好,可以考虑给他搞个算术运算,比如求个模

1393301815 发表于 2024-3-26 22:19

#!/bin/bash
for csvfile in *.csv; do
    awk -F, '{
      e5 = e7 = 0
      if ($5 > 5) {
            c5++
            if (c5 >= 3) {
                e5 = 1
            }
      } else {
            c5 = 0
      }
      if ($7 > 32) {
            c7++
            if (c7 >= 3) {
                e7 = 1
            }
      } else {
            c7 = 0
      }
      if (e5 || e7) {
            buf = $0
      }
      if (NR > 3) {
            delete buf
      }
      if (e5 || e7) {
            for (i=NR-2; i<=NR; i++) {
                if (buf) print buf >> "anomaly.log"
            }
      }
    }' $csvfile
done

chlryg 发表于 2024-3-26 23:21

1393301815 发表于 2024-3-26 22:19
#!/bin/bash
for csvfile in *.csv; do
    awk -F, '{


大佬,要求通过一行grep命令,这Shell脚本不行的o(o・`з・´o)ノ!!!

chlryg 发表于 2024-3-26 23:22

Andrea 发表于 2024-3-26 21:51
本身处理浮点数就不友好,可以考虑给他搞个算术运算,比如求个模

正则没有办法匹配浮点数码

zhufengwan 发表于 2024-3-27 01:27

是不是配合上 awk 能够实现你这个需求,可以研究研究 awk

1393301815 发表于 2024-3-27 07:03

chlryg 发表于 2024-3-26 23:21
大佬,要求通过一行grep命令,这Shell脚本不行的o(o・`з・´o)ノ!!!

你的要求一行很难实现啊

Andrea 发表于 2024-3-27 08:13

chlryg 发表于 2024-3-26 23:22
正则没有办法匹配浮点数码

目前没找到合适的方式处理浮点数,需要判断浮点数,大多是额外加工一下,或者用其他语言的脚本处理。awk 过滤后,给他算一下,这是目前我能想到的比较合适的方式了
页: [1] 2
查看完整版本: 请教一下Linux命令grep -P参数与正则表达式的过滤语法