如何使用 AWK 计算每行列中特定字符的数量并添加为新列?

如何使用 AWK 计算每行列中特定字符的数量并添加为新列?

我想计算N文件第二列中的字符数,然后将此计数打印到第三列。输入文件示例(制表符分隔):

sample1 TCTNG
sample2 CCNGGGGGTN
sample3 GGGNNNTC

所需的输出(制表符分隔):

sample1 TCTNG   1
sample2 CCNGGGGGTN  2
sample3 GGGNNNTC    3

我可以得到一个混乱的版本执行以下操作,但我想要一个单行,最好是awk.

> awk -F '\t' '{print $2}' file.txt | awk -FN '{print NF-1}' > NCount.txt
> paste -d '\t' file.txt NCount.txt

sample1 TCTNG   
    1
sample2 CCNGGGGGTN  
    2
sample3 GGGNNNTC
    3

答案1

awk 'BEGIN{FS=OFS="\t"} {print $0, gsub(/N/,"",$2)}' file
sample1 TCTNG   1
sample2 CCNGGGGGTN  2
sample3 GGGNNNTC    3

基于 : 如何打印每行的图案数?

答案2

gsub()函数返回进行替换的次数。您可以使用这个事实来计算第二个字段中的字符数N,并将该数字添加为每行上的新字段:

$ awk -F '\t' '{ $3 = gsub("N","N",$2) }; 1' file
sample1 TCTNG 1
sample2 CCNGGGGGTN 2
sample3 GGGNNNTC 3

输出是由尾随引起的1(相当于使用{ print }or { print $0 })。

设置特殊变量的值OFS以在输出中使用除默认值(空格)之外的另一个字段分隔符。在这里,我使用输入字段分隔符设置为的任何内容:

$ awk -F '\t' 'BEGIN { OFS=FS } { $3 = gsub("N","N",$2) }; 1' file
sample1 TCTNG   1
sample2 CCNGGGGGTN      2
sample3 GGGNNNTC        3

Perl 中也类似,但使用tr运算符代替gsub()

$ perl -MEnglish -a -F '\t' -e 'BEGIN { $OFS="\t"; $ORS="\n" } print @F, ($F[1] =~ tr/N/N/)' file
sample1 TCTNG   1
sample2 CCNGGGGGTN      2
sample3 GGGNNNTC        3

答案3

使用 Raku(以前称为 Perl_6)

raku -ne 'put ~$/.join("").chars if m:g/N*/;'  

输入示例:

sample0 TCTG
sample1 TCTNG
sample2 CCNGGGGGTN
sample3 GGGNNNTC

示例输出:

sample0 TCTG    0
sample1 TCTNG   1
sample2 CCNGGGGGTN  2
sample3 GGGNNNTC    3

上面的代码:首先打印 Raku$_主题变量(后跟),然后打印- 连接的匹配\t项的计数,并将作为新列添加到每行的末尾。join("")N

https://raku.org

相关内容