我的文件如下所示:
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 的行。我知道sed
and的使用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