【问题标题】:Remove lines with specific pattern删除具有特定图案的线条
【发布时间】:2018-01-16 13:56:09
【问题描述】:

我有一个具有这种特定格式的文件:

T   11722   A   330:0:0:0:0:0   315:0:0:0:0:0
T   11723   B   0:330:0:0:0:0   0:316:0:0:0:0
T   11725   C   0:327:0:0:0:0   0:314:0:0:0:0
T   11726   D   330:0:0:0:0:0   314:0:0:0:0:0
T   11727   E   0:6:0:323:0:0   0:6:0:309:0:0
T   11728   F   0:0:0:328:0:0   0:1:0:314:0:0
T   11729   G   0:325:0:0:0:0   0:315:0:0:0:0

我想删除第 4 列和第 5 列中没有两个值的所有行。

例如,如果一行具有特定格式:

T   11722   A   330:0:0:0:0:0   315:0:0:0:0:0

删除它。

如果它具有以下格式(第 4 列和第 5 列中的每列两个值):

T   11727   E   0:6:0:323:0:0   0:6:0:309:0:0

保留它。

因此,预期的结果应该是:

T   11727   E   0:6:0:323:0:0   0:6:0:309:0:0
T   11728   F   0:0:0:328:0:0   0:1:0:314:0:0

我不知道如何在 unix 下设置一些东西,但我猜应该有一个简单的方法。任何帮助将不胜感激。

非常感谢

【问题讨论】:

  • F行怎么办?
  • 根据您的逻辑,预期结果将仅包含 2 行,对吧?
  • @Pieter21,F 行第 5 列有两个值,所以我想保留它。
  • @RomanPerekhrest,是的,预期结果将仅包含 2 行。我会用预期的结果更新我的问题。
  • @AP38,我还注意到第 4 列中每列有两个值 OR 5,但不是

标签: unix awk lines text-processing


【解决方案1】:

您只是想打印 $4 或 $5 中有 2 个或多个非零值的行吗?那是:

$ awk 'gsub(/[1-9][0-9]*/,"&",$4)>1 || gsub(/[1-9][0-9]*/,"&",$5)>1' file
T 11727 E 0:6:0:323:0:0 0:6:0:309:0:0
T 11728 F 0:0:0:328:0:0 0:1:0:314:0:0

【讨论】:

  • gsub表达式之后应该变成,例如0:&:0:&:0:0,那么>1在这里是什么意思呢?你能帮忙解释一下吗?
  • & 是一个反向引用,意思是“匹配正则表达式的整个字符串”,就像在 sed 中一样。 >1 表示 greater than 1。所以 gsub() 将自己替换每个匹配的字符串并返回它执行了多少次的计数,如果计数大于 1,那么您至少找到 2 个非零数字。
  • 好的,太棒了。 gsub 中的& 用于保持匹配模式。并使用 gsub 的返回值来区分替换的次数。感谢您的解释。 :)
  • 非常感谢@EdMorton!这很好用!
  • @EdMorton,我唯一要添加到这种方法的是OFS='\t'
【解决方案2】:

awk解决方案:

awk 'function get_count(s, c, len) { 
         len=split(s,a,":"); while(len--) if(a[len]){ c++ } 
         return c 
     } BEGIN { FS=OFS="\t" }get_count($4) > 1 || get_count($5) > 1' file

  • function get_count(s, c, len) { ... } - 返回给定字符串中非零值计数的函数

  • split(s,a,":") - 通过分隔符 : 将字符串 s 拆分为数组 a

  • while(len--) if(a[len]){ c++ } - 累积非零计数

输出:

T   11727   E   0:6:0:323:0:0   0:6:0:309:0:0
T   11728   F   0:0:0:328:0:0   0:1:0:314:0:0

【讨论】:

  • 在 awk 函数中创建“局部”变量有一个技巧:将它们命名为函数的参数(但在调用它时不需要为它们提供值):function get_count(s,      c, len) { … } .当使用单个参数调用函数时,它们被初始化为零/空,并且与函数外部具有相同名称的变量分开。
猜你喜欢
  • 1970-01-01
  • 2010-11-28
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多