Regex 如何在bash中计算字符串中的连续(重复)字符?

Regex 如何在bash中计算字符串中的连续(重复)字符?,regex,bash,awk,sed,Regex,Bash,Awk,Sed,我想知道是否有一个简单的bash或AWK oneliner来获取每次重复的重复字符数 例如,考虑此字符串: AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA 是否可以获得第一次重复中的Ns数,第二次重复中的Ns数,等等 谢谢 预期结果,新行上每个重复的长度。您可以使用awk拆分每个字符上不N的字段,并打印每个字段及其长度: s='AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNT

我想知道是否有一个简单的bash或AWK oneliner来获取每次重复的重复字符数

例如,考虑此字符串:

AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA
是否可以获得第一次重复中的Ns数,第二次重复中的Ns数,等等

谢谢


预期结果,新行上每个重复的长度。

您可以使用
awk
拆分每个字符上不
N
的字段,并打印每个字段及其长度:

s='AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA'

awk -F '[^N]+' '{for (i=1; i<=NF; i++) if ($i != "") print $i, length($i)}' <<< "$s"

NNNNN 5
NNNNNNNN 8
NNNNNNN 7
下面是纯BASH解决方案:

shopt -s extglob
while read -r line; do
    [[ -n $line ]] && echo "$line ${#line}"
done <<< "${s//+([!N])/$'\n'}"

NNNNN 5
NNNNNNNN 8
NNNNNNN 7
shopt-s extglob
而read-r行;做
[[-n$line]]&&echo“$line${#line}”

完成您可以使用
awk
分割每个字符上不
N
的字段,并打印每个字段及其长度:

s='AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA'

awk -F '[^N]+' '{for (i=1; i<=NF; i++) if ($i != "") print $i, length($i)}' <<< "$s"

NNNNN 5
NNNNNNNN 8
NNNNNNN 7
下面是纯BASH解决方案:

shopt -s extglob
while read -r line; do
    [[ -n $line ]] && echo "$line ${#line}"
done <<< "${s//+([!N])/$'\n'}"

NNNNN 5
NNNNNNNN 8
NNNNNNN 7
shopt-s extglob
而read-r行;做
[[-n$line]]&&echo“$line${#line}”

完成您可以借助正则表达式方法

这是我从以下链接获得的解决方案代码

pinder=“,”
var=“text,text,text,text”

出现次数=$(grep-o“$needle”您可以借助正则表达式方法

这是我从以下链接获得的解决方案代码

pinder=“,”
var=“text,text,text,text”

出现次数=$(grep-o“$needle”下面是一个Perl一行程序:

perl -ne 'while (m/(.)(\1*)/g) { printf "%5i %s\n", length($2)+1, $1 }' <<<AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA
2 A
1 T
1 G
1 A
1 T
2 G
2 A
5 N
1 G
1 A
1 T
1 A
1 G
2 A
1 C
1 G
1 A
1 T
8 N
1 G
1 A
1 T
2 A
1 T
1 G
1 A
7 N
1 T
1 A
1 G
1 A
1 C
1 T
1 G
1 A

perl-ne'while(m/()(\1*)/g){printf“%5i%s\n”,length($2)+1,$1}'这里是一个perl单行程序:

perl -ne 'while (m/(.)(\1*)/g) { printf "%5i %s\n", length($2)+1, $1 }' <<<AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA
2 A
1 T
1 G
1 A
1 T
2 G
2 A
5 N
1 G
1 A
1 T
1 A
1 G
2 A
1 C
1 G
1 A
1 T
8 N
1 G
1 A
1 T
2 A
1 T
1 G
1 A
7 N
1 T
1 A
1 G
1 A
1 C
1 T
1 G
1 A

perl-ne'while(m/()(\1*)/g){printf“%5i%s\n”,length($2)+1,$1}'当您要求sed解决方案时,如果您的重复字符链不超过9个字符,并且如果您的字符串不包含任何分号,则可以使用此解决方案:


sed's/$/;nnnnnnnnnnn 0123456789/;:a;s/\(N\+\)\([^;]*;\1.\{9\\\)\(.\\)\(.\\\)/\2\3\4\N\3/;ta;s/[^\N]*\N/'
当您要求sed解决方案时,如果您的重复字符链不超过9个字符,并且您的字符串不包含任何分号,则可以使用此解决方案:

sed's/$/;nnnnnnnnnnn 0123456789/;:a;s/\(N\+\)\([^;]*;\1.\{9\\\)\(.\)\(.*)/\2\3\4\N\3/;ta;s/[^\N]*\N/'
简称GNUawk方法:

str='AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA'

awk -v FPAT='N+' '{for(i=1;i<=NF;i++) print $i,length($i)}' <<< $str
短GNUawk进近:

str='AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA'

awk -v FPAT='N+' '{for(i=1;i<=NF;i++) print $i,length($i)}' <<< $str
试试这两个:

第一个

sed 's/[^N]/ /g' file | awk '{for(i=1;i<=NF;i++){print $i":"length($i)}}'
sed的//[^N]//g'文件| awk'{for(i=1;i请尝试以下两种方法:

第一个

sed 's/[^N]/ /g' file | awk '{for(i=1;i<=NF;i++){print $i":"length($i)}}'
sed的//[^N]//g'文件| awk'{for(i=1;i一个简单的解决方案:

echo "$string" | grep -oE "N+" | awk '{ print $0, length}'

NNNNN 5
NNNNNNNN 8
NNNNNNN 7
编辑:
根据@Ed Morton的建议:将-P改为-E.
grep的手册页说-P是“高度实验性”的功能。
我们不需要PCRE来使用+,只要ERE就足够了。

一个简单的解决方案:

echo "$string" | grep -oE "N+" | awk '{ print $0, length}'

NNNNN 5
NNNNNNNN 8
NNNNNNN 7
编辑:
根据@Ed Morton的建议:将-P改为-E.
grep的手册页说-P是“高度实验性”的功能。

我们不需要PCREs来使用+,只需要ERE就足够了。

对于多字符的GNU awk:

$ awk -v RS='N+' 'RT{print length(RT)}' file
5
8
7

$ awk -v RS='N+' 'RT{print RT, length(RT)}' file
NNNNN 5
NNNNNNNN 8
NNNNNNN 7

使用GNU awk进行多字符RS:

$ awk -v RS='N+' 'RT{print length(RT)}' file
5
8
7

$ awk -v RS='N+' 'RT{print RT, length(RT)}' file
NNNNN 5
NNNNNNNN 8
NNNNNNN 7


你做了哪些努力?即使没有解决你的问题,也要发布它们至少要添加你的预期输出-都在一行上,空格或逗号之间,在单独的行上,等等。我对anubhava的第一个答案很满意,请参见他答案下的评论。我按照你的要求添加了预期结果。我们不需要描述对预期结果的分析(尽管也可以这样做),我们正在根据您发布的输入寻找实际的预期输出。该网站不仅为您提供问题的答案,还为其他人提供了查询问题以找到答案的存储库,因此问题必须完整(请参阅)为了将来帮助其他人。你做了哪些努力?即使没有解决你的问题,也要发布它们至少要添加你的预期输出-全部在一行上,空格或逗号之间,在单独的行上,等等。我对anubhava的第一个回答很满意,请参见他回答下的评论。我添加了预期结果,正如你要求的那样r、 我们并不是在寻找对预期结果的描述(尽管也可以这样做),我们正在根据您发布的输入查找实际的预期输出。此网站不仅为您提供问题的答案,还为其他人提供查询问题以找到答案的存储库,因此问题必须完整(请参阅)在将来帮助其他人。你得到了什么输出?另一个选择是使用:
grep-Eo'N{2,}'这很有效:
awk-F'[^N]+'{for(i=1;i@raam86:在答案中添加了详细信息。没有意识到您指的是先前定义的
s
,感谢您提供详细的答案您得到了什么输出?另一个选项是使用:
grep-Eo'N{2,}'此选项有效:
awk-F'[^N]+'{for(i=1;i@raam86:答案中添加了详细信息。没有意识到您指的是前面定义的
s
,感谢您提供的详细答案您不需要PCREs来使用
+
,只需ERE即可,因此请使用
-E
而不是
-P
,这样您的grep就不会依赖于“高度实验性”(参见手册页!)功能。@EdMorton:谢谢Ed。是的,我会从下次开始处理这个问题。让我也编辑一下。从性能角度看,您认为哪一个更好?PCRE使用与BRE和ERE非常不同的算法/regexp引擎,以适应“向前看/向后看/无论什么”,即使您不使用任何PCRE特定的功能,该引擎也会慢得多,所以BRE和ERE比PCRE快。有关详细信息,请参阅。好的。是有意义的。(y)。您不需要PCRE来使用
+
,只需要ERE,所以使用
-E
而不是
-P
,这样您的grep就不会依赖于“高度实验性”(请参阅手册页!)功能性。@EdMorton:谢谢Ed。是的,我会从下次开始处理这个问题。让我也编辑一下。从性能角度看,您认为哪一个更好?PCREs使用的是非常好的di