删除值低于(或高于)阈值的行

删除值低于(或高于)阈值的行

我的文件如下所示:

AA  110 B   10   ..  BB  15   ... BBB 20   D   F   25   D   D
AA  111 B   50   ..  BB  55   ... BBB 30   F   F   45   F   F
AA  112 C    2   ..  BB   3   ... BBB  0   D   F    0   D   F
AA  120 D    2   ..  FF   3   ... FFF  3   D   F    3   D   D

我想删除任何列中包含值 =< 10 的行。我知道sedand的使用awk '$3 !=< 10',但这只会删除第三个字段中的行。有没有办法告诉 qwk 考虑所有列?

答案1

perl来救援

$ cat ip.txt 
AA  110 B   10   ..  BB  15   ... BBB 20   D   F   25   D   D
AA  111 B   50   ..  BB  55   ... BBB 30   F   F   45   F   F
AA  112 C    2   ..  BB   3   ... BBB  0   D   F    0   D   F
AA  120 D    2   ..  FF   3   ... FFF  3   D   F    3   D   D

$ perl -ae 'print if !(grep { $_ <= 10 && /^\d+$/ } @F)' ip.txt 
AA  111 B   50   ..  BB  55   ... BBB 30   F   F   45   F   F
  • -a在空间上分割输入行并保存到@F数组
  • grep { $_ <= 10 && /^\d+$/ } @F获取@F数组中仅由数字组成且值为<= 10
  • 然后如果 grep 返回则打印行0。 around()意味着grep它将返回匹配的计数而不是元素本身

让我们测试另一个条件:

$ perl -ae 'print if !(grep { $_ < 10 && /^\d+$/ } @F)' ip.txt 
AA  110 B   10   ..  BB  15   ... BBB 20   D   F   25   D   D
AA  111 B   50   ..  BB  55   ... BBB 30   F   F   45   F   F


某些条件,例如这个问题,也可以解决grep(这可能比perl解决方案更快)

$ grep -vw '[0-9]\|10' ip.txt 
AA  111 B   50   ..  BB  55   ... BBB 30   F   F   45   F   F

$ grep -vw '[0-9]' ip.txt 
AA  110 B   10   ..  BB  15   ... BBB 20   D   F   25   D   D
AA  111 B   50   ..  BB  55   ... BBB 30   F   F   45   F   F
  • -v匹配图案以外的线条
  • -w仅匹配整个单词

答案2

在 中awk,您可以使用类似for (i = 1 ; i <= NF ; i++) { ... }循环遍历一行上的所有字段的方法。这样,就像:

awk '{for(i = 1 ; i <= NF ; i++) { 
         if ($i ~ /^[0-9]+$/ && $i <= 10) { next };
       } 
     } 1'  < input

$i ~ /^[0-9]+$/检查该字段是否仅为数字,然后与 进行比较,如果小于或等于 10,则10移动到记录(行)。next

答案3

这是用于 sed 的

sed -rn '/\b([0-9]|10)\b/!p' file

相关内容