我有一个包含三列的文件。第 3 列包含基因名称,如下所示:
Rv0729,Rv0993,Rv1408
Rv0162c,Rv0761c,Rv1862,Rv3086
Rv2790c
如何打印每行中的基因数量?
答案1
您只想添加一列及其中的列数。这可以使用以下方法完成awk
:
$ awk -F ',' '{ printf("%d,%s\n", NF, $0) }' data.in
3,Rv0729,Rv0993,Rv1408
4,Rv0162c,Rv0761c,Rv1862,Rv3086
1,Rv2790c
NF
是一个awk
变量,包含当前记录(行)中的字段(列)数。我们为每一行打印这个数字,后跟一个逗号和该行的其余部分。
另一种选择(相同的结果,但可能看起来更干净):
$ awk -F ',' 'BEGIN { OFS=FS } { print NF, $0 }' data.in
FS
是字段分隔符,用于将每个记录拆分为字段,我们在命令行上将awk
其设置为逗号(如第一个解决方案中所示)。是个-F ','
OFS
输出FS
字段分隔符,我们将其设置为与读取第一行输入之前相同。
答案2
如果您想计算模式的出现次数Rv[0-9]{4}c?
,而不是像问题主题所示的逗号分隔字段的数量,您可以这样做:
awk '{print gsub(/Rv[0-9]{4}c?/, "&"), $0}'
答案3
Perl 方法:
$ perl -F, -pae 's/^/$#F+1 . ","/e' file
3,Rv0729,Rv0993,Rv1408
4,Rv0162c,Rv0761c,Rv1862,Rv3086
1,Rv2790c
品牌-a
perl
行为类似于awk
分割由 给定的字符串上的每个输入行-F
,并将结果字段保存到数组中@F
。因此,$#F
是 中的最高数组索引@F
,并且由于数组从 开始计数0
,$#F+1
因此 是数组中元素的总数。意思-p
是“在应用 给定的脚本后打印每个输入行-e
。这是替换运算符,这里用字段数 + 1 和逗号 ( )s///
替换行的开头 ( ) 。^
$#F+1 . ","
答案4
您的问题表明第 3 列包含基因名称。我假设您的实际输入如下:
column1 column2 Rv0729,Rv0993,Rv1408
column1 column2 Rv0162c,Rv0761c,Rv1862,Rv3086
column1 column2 Rv2790c
第 3 列中的每个基因名称都包含前导Rv
子字符串。因此我们可以在 python 中这样计算它们:
$ python -c "import sys;print map(lambda x: x.split()[2].count('Rv'),sys.stdin.readlines())" < input.txt
[3, 4, 1]
结果列表显示每行中基因的计数,按各自的顺序。如果我们想让它更详细并包括基因可能不包含“Rv”字符串的可能性(但保留列3是逗号分隔值字符串的假设),我们还可以执行以下操作:
#!/usr/bin/env python
import sys
with open(sys.argv[1]) as fd:
for index,line in enumerate(fd):
columns = line.strip().split()
num_genes=len(columns[2].split(","))
print("Line "+str(index)+" contains "+str(num_genes))
测试运行:
$ ./count_genes.py input.txt
Line 0 contains 3
Line 1 contains 4
Line 2 contains 1