如何计算 Bash 中跨越多行的连续模式的出现次数?

How to count number of occurrence consecutive pattern spanning over lines in Bash?

比如我有这样一个文件。如何计算跨行的连续 N 的出现次数?

NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
CACTGCTGTCACCCTCCATGCACCTGCCCACCCTCCAAGGATCNNNNNNN
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
NNNNNNNNNNNNNNNGgtgtgtatatatcatgtgtgatgtgtggtgtgtg
gggttagggttagggttaNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
NNNNNNNNNNNNNNAGaggcatattgatctgttgttttattttcttacag
ttgtggtgtgtggtgNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

预期结果是 4 因为有 4N
我试了grep -Eozc 'N+',结果是1
如果可以,希望N的行号和长度也能显示出来

awk '=' FS='' OFS='\n' file | uniq -c | grep -c N

tr -d '\r\n' < file | grep -o 'N*' | grep -c .

输出:

4

在不使用任何外部命令的情况下 bash:

v=$(<file)X
v=${v//[[:space:]]}
v=${v//N[^N]/ }
v=${v//[^ ]}
echo ${#v}

输出:

4

假设您的数据位于名为 test.txt 的文件中:

  1. 我们从中读取所有数据。
  2. 显示符合我们模式的行(以 N 开始和结束,并且只包含 N
  3. 计算行数

所以这是执行此操作的代码:

cat test.txt | egrep -oe "^N*$" | wc -l

有点长,但很简单:

< tmp.txt \
  tr -d '\n' |  # Strip newlines
  tr -s N |     # Collapse strings of Ns to a single N
  tr -dC N |    # Strip anything that *isn't* an N
  wc -c         # Count the resulting Ns

作为 one-liner:

< tmp.txt tr -d '\n' | tr -s N | tr -dC N | wc -c

从 Bash

调用 Ruby One-Liner

您可以将 Ruby one-liner 从 Bash 中读取,无论是从文件还是标准输入中读取。例如:

$ ruby -e 'puts ARGF.read.delete("\n").scan(/N+/).count' example.txt
4

$ ruby -e 'puts ARGF.read.delete("\n").scan(/N+/).count' <<< "$str"
4

概念是吞噬整个文件,删除所有换行符,然后计算连续 N 个字符的组数。

注意:如果您想忽略孤立的 N,则只需扫描 /N{2,}/。这只会计算两个或更多 N 个字符的运行次数。