以下5列表格中包含cols1-3 位置信息, col4保持位置内类型的命中(有3种可能的类型 - 序列号:1,2,3),col5保存特定的命中数类型(可以是零或任意数量的命中)。
请注意,有几个地点有多种类型的点击。 对于前者location [chrX 93554661 94234661]有5个字及'' 2', 和#3;'类型的3次点击。
chrX 93554661 94234661 2 5
chrX 93554661 94234661 3 3
chrX 94234661 94674661 1 1
chrX 95044661 96804661 1 4
chrX 95044661 96804661 2 1
chrX 95044661 96804661 3 6
chrX 96804661 97684661 1 4
chrX 97684661 98964661 1 3
chrX 98964661 99724661 0 0
chrX 99724661 101124661 1 4
chrX 101124661 101524661 1 4
chrX 101524661 103124661 1 5
chrX 101524661 103124661 3 1
chrX 103124661 103444661 3 2
chrX 103444661 104044661 1 1
chrX 103444661 104044661 2 4
我想重新格式化表格,以便在新表格中,最右边的三列代表每个位置中每种类型的点击总数,这样第4,5,6列将代表连续命中类型1,2,3,分别为。
理想的格式是:
chrX 93554661 94234661 0 5 3
chrX 94234661 94674661 1 0 0
chrX 95044661 96804661 4 1 6
chrX 96804661 97684661 4 0 0
chrX 97684661 98964661 3 0 0
chrX 98964661 99724661 0 0 0
chrX 99724661 101124661 4 0 0
chrX 101124661 101524661 4 0 0
chrX 101524661 103124661 5 0 1
chrX 103124661 103444661 0 0 2
chrX 103444661 104044661 1 4 0
我目前的解决方案可以完成这项工作 - 但我怀疑它非常繁琐,而且我对学习更优雅的解决方案非常感兴趣。请将您的解决方案仅限于UNIX系统,并使用更简单的awk版本而不是gawk。
这是我的解决方案:
awk -F"\t" 'NF>1{a[$1"\t"$2"\t"$3] = a[$1"\t"$2"\t"$3]","$4"~"$5};END{for(i in a) {n=split(a[i],g,",")-1; printf i"\t" ;for(z=2;z<=n+1;z++){split(g[z],w,"~"); if(w[1]!=""){printf "%s",w[1]"\t"w[2]"\t";}}printf "\n"}}'|sort -t$'\t' -k1,1 -k2,2n|awk '{printf "%s",$0;for(i=NF+1;i<=9;i++){printf "%s",0"\t"};printf "\n"}' |awk -F"\t" '{OFS="\t"}{$($4+9)=$5;$($6+9)=$7;$($8+9)=$9;print $0}'|awk 'BEGIN { FS = OFS = "\t" } { for(i=1; i<=12; i++) if($i ~ /^ *$/) $i = 0 }; 1'|awk -F "\t" '{OFS="\t"}{print $1,$2,$3,$10,$11,$12}'
答案 0 :(得分:2)
如果您的Input_file与显示的示例相同,并且您不担心输出的顺序应该与Input_file相同,那么以下内容可能对您有帮助。
awk '
{
a[$1 FS $2 FS $3 FS $4]+=$5;
b[$1 FS $2 FS $3]
}
END{
for(i in b){
printf("%s %s %s %s\n",i,a[i FS "1"]?a[i FS "1"]:0,a[i FS "2"]?a[i FS "2"]:0, a[i FS "3"]?a[i FS "3"]:0)
}
}
' Input_file
编辑:如果您需要输出与Input_file的顺序相同,那么以下内容可能对您有帮助。
awk '
!b[$1 FS $2 FS $3]{
c[++i]=$1 FS $2 FS $3
}
{
a[$1 FS $2 FS $3 FS $4]+=$5;
b[$1 FS $2 FS $3]=$1 FS $2 FS $3
}
END{
for(j=1;j<=i;j++){
printf("%s %s %s %s\n",c[j],a[b[c[j]] FS "1"]?a[b[c[j]] FS "1"]:0,a[b[c[j]] FS "2"]?a[b[c[j]] FS "2"]:0, a[b[c[j]] FS "3"]?a[c[j] FS "3"]:0)
}
}
' Input_file
输出如下。
chrX 93554661 94234661 0 5 3
chrX 94234661 94674661 1 0 0
chrX 95044661 96804661 4 1 6
chrX 96804661 97684661 4 0 0
chrX 97684661 98964661 3 0 0
chrX 98964661 99724661 0 0 0
chrX 99724661 101124661 4 0 0
chrX 101124661 101524661 4 0 0
chrX 101524661 103124661 5 0 1
chrX 103124661 103444661 0 0 2
chrX 103444661 104044661 1 4 0
答案 1 :(得分:2)
这个怎么样:我假设您的数据是以制表符分隔的
sort -k1,1 -k2,3n file | awk -F'\t' -v OFS='\t' '
function init() { v[1] = v[2] = v[3] = 0 }
function output() { print prev, v[1], v[2], v[3] }
{ key = $1 FS $2 FS $3 }
NR == 1 { prev = key; init() }
key != prev { output(); init() }
{ v[$4] = $5; prev = key }
END { output() }
'
答案 2 :(得分:1)
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{ curr = $1 FS $2 FS $3 }
curr != prev { if (NR>1) prt(); prev=curr }
{ cnt[$4] += $5 }
END { prt() }
function prt() {
print prev, cnt[1]+0, cnt[2]+0, cnt[3]+0
delete cnt
}
$ awk -f tst.awk file
chrX 93554661 94234661 0 5 3
chrX 94234661 94674661 1 0 0
chrX 95044661 96804661 4 1 6
chrX 96804661 97684661 4 0 0
chrX 97684661 98964661 3 0 0
chrX 98964661 99724661 0 0 0
chrX 99724661 101124661 4 0 0
chrX 101124661 101524661 4 0 0
chrX 101524661 103124661 5 0 1
chrX 103124661 103444661 0 0 2
chrX 103444661 104044661 1 4 0
答案 3 :(得分:0)
不假设输入是有序的:
$ cat test.awk
BEGIN { FS=OFS="\t" }
!sum[$1 FS $2 FS $3]{
sum[$1 FS $2 FS $3] = "000"
}
{
values = sum[$1 FS $2 FS $3]
if ($4 > 0)
sum[$1 FS $2 FS $3] = substr(values, 1, $4 - 1) substr(values, $4, 1) + $5 substr(values, $4 + 1, 3 - $4)
}
END {
for (i in sum) {
print i, substr(sum[i],1,1), substr(sum[i],2,1), substr(sum[i],3,1)
}
}
$ awk -f test.awk input.txt
chrX 103444661 104044661 1 4 0
chrX 99724661 101124661 4 0 0
chrX 95044661 96804661 4 1 6
chrX 93554661 94234661 0 5 3
chrX 96804661 97684661 4 0 0
chrX 101124661 101524661 4 0 0
chrX 103124661 103444661 0 0 2
chrX 94234661 94674661 1 0 0
chrX 98964661 99724661 0 0 0
chrX 101524661 103124661 5 0 1
chrX 97684661 98964661 3 0 0