我有一个大数据文本文件(超过100,000行),格式为:
0.000197239;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=CLCNKA;GeneDetail.refGene=.;ExonicFunc
0.00118343;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=CLCNKA;GeneDetail.refGene=.;ExonicFunc.refGene=nonsynonymous_SNV;
0.00276134;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=CLCNKA;GeneDetail.refGene=.;
0.0607495;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=CLCNKA;GeneDetail.refGene=.;ExonicFunc.refGene=nonsynonymous_SNV;
0.00670611;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=XDH;GeneDetail.refGene=.;ExonicFunc.refGene=nonsynonymous_SNV;
0.000197239;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=XDH;GeneDetail.refGene=.;ExonicFunc.refGene=nonsynonymous_SNV;
0.000394477;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=GRK4;GeneDetail.refGene=.;ExonicFunc.refGene=nonsynonymous_SNV;
0.0108481;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=GRK4;GeneDetail.refGene=.;ExonicFunc.refGene=nonsynonymous_SNV;
0.000394477;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=GRK4;GeneDetail.refGene=.;ExonicFunc.refGene=nonsynonymous_SNV;
0.0108481;AN=192;NS=2535;ANNOVAR_DATE=2015-12-14;Func.refGene=exonic;Gene.refGene=GRK4;GeneDetail.refGene=.;ExonicFunc.refGene=nonsynonymous_SNV;
现在,每行包含一个基因名称,例如在最初的4行中有CLCNKA
个基因。我使用grep
命令来计算此数据文件中每个基因名称的频率,如下:
grep -w "CLCNKA" my_data_file | wc -l
在单独的文件中有大约300个基因要在上面的数据文件中搜索。有些专家可以写一个简单的shell script
来循环从一个列表中逐一取基因名称,并将其频率存储在一个单独的文件中。所以,输出文件将是这样的:
CLCNKA 4
XDH 2
GRK4 4
答案 0 :(得分:2)
awk
是你的朋友
awk '{sub(/^.*Gene\.refGene=/,"");sub(/;.*$/,"");
genelist[$0]++}END{for(i in genelist){print i,genelist[i]}}' file
<强>输出强>
GRK4 4
CLCNKA 4
XDH 2
旁注:这可能不会按照它们在文件中出现的顺序为您提供基因名称频率。我想这不是一个要求。
答案 1 :(得分:2)
count the frequency of each gene name in this data file
)就是这样:
$ awk -F'[=;]' '{cnt[$11]++} END{for (gene in cnt) print gene, cnt[gene]}' file
GRK4 4
CLCNKA 4
XDH 2
虽然其他人都认为您想要计算存在于不同文件中的特定基因,因为这是您的主题行,提议的算法和其他文本的状态。
如果其他人都是对的,那么你需要这个调整来阅读&#34;基因&#34;首先归档并且只计算&#34;文件&#34;中的基因。在&#34;基因&#34;中列出:
awk -F'[=;]' 'NR==FNR{genes[$0]; next} $11 in genes{cnt[$11]++} END{for (gene in cnt) print gene, cnt[gene]}' genes file
GRK4 4
CLCNKA 4
XDH 2
您的示例没有帮助,因为它会产生相同的输出并解释您的要求,因此请编辑您的问题以阐明您想要的内容。特别是如果有一些您不想要计算的基因,那么请在样本输入中包含含有这些基因的行。
答案 2 :(得分:1)
这也可以在纯 bash 中完成,方法是使用associative array功能计算频率:
#!/bin/bash
# declare assoc array
declare -A freq
# split stdin input csv
for gene in $(cut -d ';' -f 6|cut -d = -f 2);do
let freq[$gene]++
done
# loop over array keys
for key in ${!freq[@]}; do
echo ${key} ${freq[$key]}
done
答案 3 :(得分:1)
依赖于 uniq 命令的更简单的解决方案:
#!/bin/bash
cut -d ';' -f 6|cut -d = -f 2|sort|uniq -c|while read -a kv;do
echo ${kv[1]} ${kv[0]}
done
答案 4 :(得分:0)
这是单行:
sed "s/.*Gene.refGene=//;s/\;.*//" test | sort | uniq -c | awk '{print $2,$1}'
sed
- 将删除除基因名称以外的所有内容
sort
将按名称进行排序
uniq -c
- 将计算基因重复的数量
带有swap uniq输出的awk
(默认为:计数模式)
答案 5 :(得分:0)
要保留订单,请按照示例中的说明对输入文件进行排序:
$ perl -lne '
($k) = /Gene\.refGene=([^;]+)/;
push(@o, $k) if !$h{$k}++;
END { print "$_\t$h{$_}" foreach (@o) }' ip.txt
CLCNKA 4
XDH 2
GRK4 4
如果没有,请使用哈希变量来增加用作键的基因名称和用于存储键顺序的数组
{{1}}
答案 6 :(得分:0)
如果你只搜索一个基因列表,这是一种低效但直截了当的方式
read g; do echo -n $g " "; grep -c $g file; done < genes
假设您的基因在基因文件中一次列出一个。
如果您的文件结构已修复,则更高效的版本将是
awk 'NR==FNR{genes[$1];next}
{sub(/Gene.refGene=/,"",$6)}
$6 in genes{count[$6]++}
END{for(g in count) print g,count[g]}' genes FS=';' file