我想知道是否有一个简单的bash或AWK oneliner来获取重复字符的数量,每次重复。
例如考虑这个字符串:
AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA
是否可以获得第一次重复中的Ns数量,第二次重复中的Ns数量等?
谢谢!
预期结果,每行重复的长度。
答案 0 :(得分:6)
您可以使用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
另一种选择是使用grep + awk
:
grep -Eo 'N+' <<< "$s" | awk '{print $1, length($1)}'
这是纯BASH解决方案:
shopt -s extglob
while read -r line; do
[[ -n $line ]] && echo "$line ${#line}"
done <<< "${s//+([!N])/$'\n'}"
NNNNN 5
NNNNNNNN 8
NNNNNNN 7
BASH解决方案详情:
non-N
个字符,并用+([!N])/$'\n'}"
while
循环,我们遍历N
个字符答案 1 :(得分:4)
一个简单的解决方案:
echo "$string" | grep -oE "N+" | awk '{ print $0, length}'
NNNNN 5
NNNNNNNN 8
NNNNNNN 7
修改强>
根据@ Ed-Morton的建议:将-P改为-E
grep的man页面说-P是“高度实验性”的功能
我们不需要PCRE使用+,只需ERE即可。
答案 2 :(得分:3)
使用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
答案 3 :(得分:2)
这是一个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
m/(.)(\1*)/
连续匹配尽可能多的相同字符,/g
导致匹配在下一次迭代时再次拾取,只要该字符串仍包含我们尚未包含的内容匹配。所以我们用相同字符的块循环遍历字符串,并在每次迭代时打印第一个字符以及整个匹配字符串的长度。
第一对括号在(剩余不匹配的)行的开头捕获一个字符,\1
表示重复此字符。 *
量词与此匹配的次数尽可能多。
如果您只对N:s感兴趣,可以将第一个括号更改为(N)
,或者添加类似printf("%7i %s\n", length($2), $1) if ($1 == "N")
的条件。同样,如果您只想要有重复的匹配(多次出现),您可以说\1+
而不是\1*
或添加类似... if length($2) >= 1
的条件。
答案 4 :(得分:1)
当您要求使用sed解决方案时,如果您的重复字符链不超过9个字符并且您的字符串不包含任何分号,则可以使用此解决方案:
sed 's/$/;NNNNNNNNN0123456789/;:a;s/\(N\+\)\([^;]*;\1.\{9\}\)\(.\)\(.*\)/\2\3\4\n\3/;ta;s/[^\n]*\n//'
答案 5 :(得分:1)
试试这两个:
第一个
sed 's/[^N]/ /g' file | awk '{for(i=1;i<=NF;i++){print $i":"length($i)}}'
第二个
cat file | tr -c 'N' ' ' | awk '{for(i=1;i<=NF;i++){print $i":"length($i)}}'
答案 6 :(得分:0)
短GNU awk 方法:
str='AATGATGGAANNNNNGATAGAACGATNNNNNNNNGATAATGANNNNNNNTAGACTGA'
awk -v FPAT='N+' '{for(i=1;i<=NF;i++) print $i,length($i)}' <<< $str
输出:
NNNNN 5
NNNNNNNN 8
NNNNNNN 7
答案 7 :(得分:-1)
你可以学习正则表达式方法。
这是我从以下链接获得的解决方案代码
Count occurrences of a char in a string using Bash
needle=","
var="text,text,text,text"
number_of_occurrences=$(grep -o "$needle" <<< "$var" | wc -l)
你可以看到我们得到了&#34; $ needle&#34;的出现次数。很容易在WC(字数统计)的帮助下。
您可以循环播放以满足您的需求。