计算“ X”之间的行数


13

我想计算“ X”之间的线。这只是一个例子。我必须将代码应用于复杂的生物学结果。如果您可以建议一些命令(最好使用)awkgrep或者sed我很熟悉这些命令,我将不胜感激。

例:

X
Y
Y
Y
X
Y
Y
Y
Y
X
Y
X

所需输出:

3
4
1

2
如果您将从事此领域的工作,可能会对生物信息学感兴趣。
terdon

Answers:


13

awk

$ awk '!/X/{count++}/X/{print count; count = 0}' input

3
4
1

对不包含在内的每一行增加一个计数X;打印并重置包含的行的计数X


2
如果第一行不是an X,则此解决方案仍将计数并输出第一行,直到与X匹配的第一行为止。EX(不能在注释中添加新行,但请考虑每个字符之间有新行; P):Y X Y Y X Y Y Y将输出:1 2
Dan Dan

1
@muru这是不行的,如果没有X在结束(需外接END{if (count)print count}),并产生空行,其中X是开始避开你可以添加/X/&&count状况也
αғsнιη

1
h 一条评论抱怨说,Y不应将前导s计数,因为前导s不在两个Xs 之间。其他人则抱怨尾随Ys不算在内,因为它们并不完全在两个Xs 之间。如果需要,我将等待OP澄清;我对这个答案很满意,因为直到那时。
muru

12
$ awk '/X/ && prev{print NR-prev-1} /X/{prev=NR}' file
3
4
1

怎么运行的:

Awk逐行隐式读取输入文件。

  • /X/ && prev{print NR-prev-1}

    对于包含X且如果我们先前已将值分配给的任何行prev,则打印出当前行的编号NR减去prev负1。

  • /X/{prev=NR}

    对于包含的任何行X,请将变量prev设置为当前行号NR


4
恩,很好。虐待NR给我一个主意:awk '/X/{print NR - 1; NR = 0}' foo
大师

谢谢,它给了我确切的信息。这是必需的。
Rhea

Muro:很好,很棘手。除了打印一个值太多外,它在gawk和mawk下对我有用。我很好奇这是否是保证行为。@EdMorton?
John1024 '17

3
@rhea除非您的第一行始终是an X,否则正如我在muru的答案中的注释中所解释的那样,两个答案之间的输出会有细微的差别。

1
@ John1024谢谢!希望对我有帮助。
Rhea

6

另一个简单的awk方法适用于OP的样本数据,如果X不是在第一个,甚至不是最后一个或重复的Xs中,也可以使用。

awk -v RS='X' 'NF{print NF}' infile

当每行中只有一个字段具有默认FS的任何空格时,上面的方法是正确的,否则下面的方法通常进行修改以按计数。您可以在此处输入X代替您的PATTERN

awk -F'\n' -v RS='X' 'NF>2{print NF-2}'

输入样例:

X
Y YYY Y
YY
YY Y YY YY Y Y
X
Y Y Y
X
Y
Y
X
X

输出为:

3
1
2

1

这里的大多数答案与使用Awk程序中嵌入的正则表达式要计算的行的内容匹配。如果需要将行与可能包含特殊字符的内容(Awk或正则表达式)进行匹配,则最好实际比较字符串是否相等。因此,我提出以下Awk脚本作为muru答案的变体:

BEGIN {
    count = 0;
}

{
    if ($0 == needle) {
        if (count) {
            print count;
            count = 0;
        }
    } else {
        count++;
    }
}

将其存储为文本文件,例如count-rows.awk,并按以下方式调用它:

awk -f count-rows.awk -v needle=X input

您可以needle根据自己的喜好调整值。此方法的优点是,您可以从shell脚本中使用具有任意值的调用程序,needle而不会产生问题:

awk -f count-rows.awk -v needle="$needle" input
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.