3

输入是这样的:

CNNCC
NCNCN
NNNCC
CCNNN
CCCCN

输出应该是这样的:

CNNCC
CCCCN

这意味着,如果出现3 次以上N,则该行将被过滤掉,否则将被保留。(在我的工作中,我需要过滤掉超过500 N 的 100000 行,所以性能可能很重要)

我知道如何N在awk中按连续过滤,但我不知道如何计算不连续的..

有人对此有想法吗?解决方案shell 也可以。

在所有答案中,我认为这个可能是最简单的:

awk -FN 'NF<=3'
4

7 回答 7

5
awk -FN -vcount=3 'NF<=count'

awk或者,对于不支持该-v选项的老年人,

awk -FN 'NF<=count' count=3

该命令使用目标字符作为字段分隔符,最大允许出现次数为count. 通过将生成的字段数与我们进行比较,count我们可以有选择地打印符合我们标准的行。

该声明的意图不是很明显,因此可读性较差。然而,它确实具有 char 和count参数化的优点,因此可以轻松地重复用于不同的设置。

诚然,这对于大量count. 将最大字段数设置为count+1将克服此性能问题,不幸的-mf是 gawk 忽略了该选项。

于 2012-10-31T11:11:49.803 回答
4

这可能对您有用(GNU sed):

sed -r '/(.*N){3}/d' file

或者

sed 's/N/&/3;T;d' file
于 2012-10-31T12:22:38.443 回答
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
于 2012-10-31T11:11:11.820 回答
2

没有爱grep

count=3
egrep -v "(.*N){$count}" file

更多信息:

-v反转匹配,因此这会查找不包含 3 个 N 的行(如果该行有超过 3 个 N,则它包含 3 个 N)。

egrep等同于grep -E使用扩展正则表达式 (ERE),在此处使用,因此( )不必{ }转义。

于 2012-10-31T15:06:17.237 回答
2

你可以gsub用来计算:

awk 'gsub(/N/,"N") < 3' file.txt

结果:

CNNCC
CCCCN
于 2012-10-31T11:15:15.063 回答
1

Perl 单行

perl -ne 'print if tr/N/N/ < 3'
于 2012-10-31T14:11:12.533 回答
0

这将做到:

gawk '/N.*N.*N/ { next; } { print; }'
于 2012-10-31T10:57:44.680 回答