从CSV中提取匹配行

从CSV中提取匹配行,csv,awk,Csv,Awk,我有一个文件如下所示: 64fe12c7-b50c-4f63-b292-99f4ed74e5aa, ip, 1.2.3.4, 64fe12c7-b50c-4f63-b292-99f4ed74e5aa, ip, 4.5.6.7, bacd8a9d-807f-4ae9-95d2-f7cc17222cab, ip, 0.0.0.0/0, silly string bacd8a9d-807f-4ae9-95d2-f7cc17222cab, ip, 0.0.0.0/0, crazy town db86

我有一个文件如下所示:

64fe12c7-b50c-4f63-b292-99f4ed74e5aa, ip, 1.2.3.4, 
64fe12c7-b50c-4f63-b292-99f4ed74e5aa, ip, 4.5.6.7, 
bacd8a9d-807f-4ae9-95d2-f7cc17222cab, ip, 0.0.0.0/0, silly string
bacd8a9d-807f-4ae9-95d2-f7cc17222cab, ip, 0.0.0.0/0, crazy town
db86d211-0b09-4a8f-b222-a21a54ad2f9c, ip, 8.9.0.1, wild wood
db86d211-0b09-4a8f-b222-a21a54ad2f9c, ip, 0.0.0.0/0, wacky tabacky
611f8cf5-f6f2-4f3a-ad24-12245652a7bd, ip, 0.0.0.0/0, cuckoo cachoo
我想提取一个列表,其中只包含唯一的guid

  • GUID在第3列中没有0.0.0.0/0
  • 第3列与0.0.0.0/0匹配,并且存在多个GUID实例,其中至少有一个匹配项不是0.0.0.0/0
  • 在这种情况下,所需输出为:

    64fe12c7-b50c-4f63-b292-99f4ed74e5aa
    db86d211-0b09-4a8f-b222-a21a54ad2f9c
    
    试着想清楚这一点,我觉得我应该创建一个数组/唯一guid的列表,然后对匹配的行进行grep处理,并运行上面两个条件的过程,但我不知道用一个简短的脚本或者grep/awk/sort/cut一行来实现这一点的最佳方法。谢谢你的帮助


    (原始文件是一个4列csv,其中第4列通常为空)

    听起来可以通过三步管道完成:

  • 过滤出第3列为
    0.0.0.0/0
    的行:
    grep-v'^[^,]*,[^,]*,*0\.0\.0/0',
  • 选择第1列:
    cut-d,-f1
  • 仅打印唯一元素:
    sort-u
    (或者,如果所有重复项相邻,
    uniq

  • Awk
    解决方案:

    awk -F',[[:space:]]*' '$3 !~ /^(0\.){3}0\/0/{ guids[$1] }
                           END{ for(k in guids) print k }' testfile.txt
    
    输出:

    db86d211-0b09-4a8f-b222-a21a54ad2f9c
    64fe12c7-b50c-4f63-b292-99f4ed74e5aa
    

    使用
    awk

    awk -F, '$3 !~/0\.0\.0\.0\/0/ && !seen[$1]++{print $1}' infile
    
    说明:

    $ cat infile
    64fe12c7-b50c-4f63-b292-99f4ed74e5aa, ip, 1.2.3.4, 
    64fe12c7-b50c-4f63-b292-99f4ed74e5aa, ip, 4.5.6.7, 
    bacd8a9d-807f-4ae9-95d2-f7cc17222cab, ip, 0.0.0.0/0, silly string
    bacd8a9d-807f-4ae9-95d2-f7cc17222cab, ip, 0.0.0.0/0, crazy town
    db86d211-0b09-4a8f-b222-a21a54ad2f9c, ip, 8.9.0.1, wild wood
    db86d211-0b09-4a8f-b222-a21a54ad2f9c, ip, 0.0.0.0/0, wacky tabacky
    611f8cf5-f6f2-4f3a-ad24-12245652a7bd, ip, 0.0.0.0/0, cuckoo cachoo
    
    $ awk -F, '$3 !~/0\.0\.0\.0\/0/ && !seen[$1]++{print $1}' infile
    64fe12c7-b50c-4f63-b292-99f4ed74e5aa
    db86d211-0b09-4a8f-b222-a21a54ad2f9c
    
    • 3美元~/0\.0\.0\.0\/0/
      字段3与regexp和(
      &&
      )不匹配
    • !已看到[$1]+
      字段1以前未看到过(每当awk看到重复键(
      $1
      ),数组值将增加1,我们仅使用逻辑求反打印值一次)
      • 是逻辑求反运算符
      • 所见
        为数组
      • $1
        是数组键
      • ++
        增量运算符(当前上下文后增量)
    • print$1
      print field1
    测试结果:

    $ cat infile
    64fe12c7-b50c-4f63-b292-99f4ed74e5aa, ip, 1.2.3.4, 
    64fe12c7-b50c-4f63-b292-99f4ed74e5aa, ip, 4.5.6.7, 
    bacd8a9d-807f-4ae9-95d2-f7cc17222cab, ip, 0.0.0.0/0, silly string
    bacd8a9d-807f-4ae9-95d2-f7cc17222cab, ip, 0.0.0.0/0, crazy town
    db86d211-0b09-4a8f-b222-a21a54ad2f9c, ip, 8.9.0.1, wild wood
    db86d211-0b09-4a8f-b222-a21a54ad2f9c, ip, 0.0.0.0/0, wacky tabacky
    611f8cf5-f6f2-4f3a-ad24-12245652a7bd, ip, 0.0.0.0/0, cuckoo cachoo
    
    $ awk -F, '$3 !~/0\.0\.0\.0\/0/ && !seen[$1]++{print $1}' infile
    64fe12c7-b50c-4f63-b292-99f4ed74e5aa
    db86d211-0b09-4a8f-b222-a21a54ad2f9c
    

    只需添加另一个可能的解决方案,与另一个建议的
    awk
    解决方案类似(但更丑陋,并且使用多个命令)。如果我理解正确的话,你的情况2已经被1考虑在内了。在任何情况下,以下
    awk+sort
    对我都有效:

    awk -F, '$3!~/^ 0\.0\.0\.0\/0/ {print $1}' file.csv | sort -u
    
    使用
    排序
    上的
    -u
    (唯一)标志,可以排除重复项。并非完全万无一失,但在这种情况下有效


    希望有帮助

    谢谢,但这对我不起作用<代码>cat testfile.txt | grep-v'^[^,]*,[^,]*,*0\.0\.0/0',| cut-d,-f1 | sort-u 611f8cf5-f6f2-4f3a-ad24-12245652a7bd 64fe12c7-b50c-4f63-b292-99f4ed74e5aa bacd8d-807f-4ae9-95d2-f7cc1722cab db86d211-0b09-4a8f-b222-a2542ad9c该命令生成文件中的uniques。