输入如下:
CNNCC
NCNCN
NNNCC
CCNNN
CCCCN
输出应该是这样的:
CNNCC
CCCCN
这意味着,如果超过3次出现N
,该行将被过滤掉,否则会被保留。 (在我的工作中,我需要过滤掉超过 500 N的100000行,因此性能可能很重要)
我知道如何在awk中按连续N
进行过滤,但我不知道如何计算不连续的..
有没有人有这方面的想法? shell
中的解决方案也可以。
在所有答案中,我认为这可能是最简单的:
awk -FN 'NF<=3'
答案 0 :(得分:5)
awk -FN -vcount=3 'NF<=count'
或者,对于不支持awk
选项的旧版-v
,
awk -FN 'NF<=count' count=3
该命令使用目标字符作为字段分隔符,最大允许出现次数为count
。通过将结果字段数与count
进行比较,我们可以选择性地打印符合我们标准的行。
声明的意图不是很明显,因此可读性较差。但它具有使char和count
参数化的优点,因此可以很容易地重用于不同的设置。
不可否认,这对于大量count
来说效率不高。将最大字段数设置为count+1
可以克服此性能问题,遗憾的是gawk会忽略-mf
选项。
答案 1 :(得分:4)
这可能适合你(GNU sed):
sed -r '/(.*N){3}/d' file
或
sed 's/N/&/3;T;d' file
答案 2 :(得分:2)
使用相同正则表达式的sed
解决方案:
% sed '/N.*N.*N/d'
d
删除任何地方有三个或更多N
个字符的每一行。
示例:强>
% sed '/N.*N.*N/d' <<EOF
`heredoc> CNNCC
`heredoc> NCNCN
`heredoc> NNNCC
`heredoc> CCNNN
`heredoc> CCCCN
`heredoc> EOF
CNNCC
CCCCN
答案 3 :(得分:2)
您可以使用gsub
来计算:
awk 'gsub(/N/,"N") < 3' file.txt
结果:
CNNCC
CCCCN
答案 4 :(得分:2)
对grep
不爱?
count=3
egrep -v "(.*N){$count}" file
更多信息:
-v
反转匹配,因此找到不包含3个N的行(如果行超过3个N,则包含3个N)。
egrep
相当于使用扩展正则表达式(ERE)的grep -E
,此处使用,因此( )
和{ }
不必转义。
答案 5 :(得分:1)
Perl one-liner
perl -ne 'print if tr/N/N/ < 3'
答案 6 :(得分:0)
这样做:
gawk '/N.*N.*N/ { next; } { print; }'