input是这样的:
CNNCC NCNCN NNNCC CCNNN CCCCN
输出应该是这样的:
CNNCC CCCCN
也就是说,如果N
出现的次数超过3次,则该行将被过滤掉 ,否则保留。 (在我的工作中,我需要过滤超过500 N的100000行,因此性能可能很重要)
我知道如何在awk中连续N
进行过滤,但我不知道如何计算不连续的。
有没有人有这个想法? 在shell
解决scheme也可以。
在所有的答案中,我认为这可能是最简单的:
awk -FN 'NF<=3'
awk -FN -vcount=3 'NF<=count'
或者,对于不支持-v
选项的较旧的awk
,
awk -FN 'NF<=count' count=3
该命令使用目标字符作为字段分隔符,允许的最大出现count
为count
。 通过比较count
的字段count
我们可以选择性地打印符合我们标准的行。
声明的意图并不明显,因此不太可读。 但它的优点是具有参数化的字符和count
,因此可以轻松地重复使用不同的设置。
无可否认,这对大量的count
来说效率不高。 设置最大字段count+1
会克服这个性能问题,不幸的是-mf
选项被gawk忽略。
这可能适用于你(GNU sed):
sed -r '/(.*N){3}/d' file
要么
sed 's/N/&/3;T;d' file
使用相同正则表达式的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
你可以使用gsub
来计算:
awk 'gsub(/N/,"N") < 3' file.txt
结果:
CNNCC CCCCN
不爱grep
?
count=3 egrep -v "(.*N){$count}" file
更多信息:
-v
反转匹配,所以这找到不包含3个N的行(如果该行具有多于3个N,则包含3个N)。
egrep
等同于使用扩展正则表达式(ERE)的grep -E
,这里使用( )
和{ }
不必转义。
Perl单线程
perl -ne 'print if tr/N/N/ < 3'
这将做到这一点:
gawk '/N.*N.*N/ { next; } { print; }'