我正在尝试从我的制表符分隔文件中删除冗余数据,该文件看起来像这样
chr1 1841 1851 4
chr1 1991 2001 3
chr1 2491 2501 2
chr1 2491 2501 2
chr1 2501 2511 1
chr1 2681 2691 3
chr1 2881 2891 4
chr1 2891 2901 1
chr1 3241 3251 1
chr1 3241 3251 6
条件是:如果前三列相同,则应使用第四列(最高值)中的值来获取前三列和第四列。如果存在平局,则只应打印4列中的值。
因此,对于上述输入,理想输出应为
chr1 1841 1851 4
chr1 1991 2001 3
chr1 2491 2501 2
chr1 2501 2511 1
chr1 2681 2691 3
chr1 2881 2891 4
chr1 2891 2901 1
chr1 3241 3251 6
我是怎么接近的:
首先对文件进行排序,然后将其搞砸了
sort file | awk -F '\t' 'NR==1{last = $1; max = 0} {if (last != $1) {printf "%s\t%e\n", last, max; last = $1; max = $4} else if (max < $4) max = $4} END{printf "%s\t%e\n", last, max}'
请帮助
答案 0 :(得分:3)
$ sort -k1 -k2,3n -k4nr file | awk '!a[$1,$2,$3]++'
chr1 1841 1851 4
chr1 1991 2001 3
chr1 2491 2501 2
chr1 2501 2511 1
chr1 2681 2691 3
chr1 2881 2891 4
chr1 2891 2901 1
chr1 3241 3251 6
答案 1 :(得分:1)
sort -k 1,3 -k 4r file | awk 'last != $1" "$2" "$3 { print; last = $1" "$2" "$3; }'
我的输出:
chr1 1841 1851 4
chr1 1991 2001 3
chr1 2491 2501 2
chr1 2501 2511 1
chr1 2681 2691 3
chr1 2881 2891 4
chr1 2891 2901 1
chr1 3241 3251 6
答案 2 :(得分:1)
您可以将前三列用作哈希的键,并且只记住具有最大$4
的那一列:
<infile awk '
BEGIN { FS = OFS = "\t" }
$4 > h[$1,$2,$3] { h[$1,$2,$3] = $4 }
END {
for(k in h) {
split(k, a, SUBSEP)
print a[1], a[2], a[3], h[k]
}
}
' | sort -k1 -k2n,3n
输出:
chr1 1841 1851 4
chr1 1991 2001 3
chr1 2491 2501 2
chr1 2501 2511 1
chr1 2681 2691 3
chr1 2881 2891 4
chr1 2891 2901 1
chr1 3241 3251 6
如果你使用的是GNU awk,你也可以在awk中进行排序:
parse.awk
BEGIN { FS = OFS = "\t" }
$4 > h[$1,$2,$3] { h[$1,$2,$3] = $4 }
END {
len = asorti(h, d)
for(i=1; i<=len; i++) {
flen = split(d[i], a, SUBSEP)
for(j=1; j<=flen; j++)
printf "%s%s", a[j], OFS
print h[d[i]]
}
}
然后像这样运行:
awk -f parse.awk infile
答案 3 :(得分:1)
这个单行应该给出输出:
awk -F'\t' -v OFS="\t" '{t=$1FS$2FS$3;if(!(t in a)||a[t]<$4)a[t]=$4}END{for(x in a) print x,a[x]}' file|sort
清晰格式:
awk -F'\t' -v OFS="\t" '{
t=$1FS$2FS$3
if(!(t in a)||a[t]<$4)
a[t]=$4
}
END{for(x in a) print x,a[x]}' file|sort
如果您使用数据文件运行:
kent$ cat file
chr1 1841 1851 4
chr1 1991 2001 3
chr1 2491 2501 2
chr1 2491 2501 2
chr1 2501 2511 1
chr1 2681 2691 3
chr1 2881 2891 4
chr1 2891 2901 1
chr1 3241 3251 1
chr1 3241 3251 6
kent$ awk -F'\t' -v OFS="\t" '{t=$1FS$2FS$3;if(!(t in a)||a[t]<$4)a[t]=$4}END{for(x in a) print x,a[x]}' file|sort
chr1 1841 1851 4
chr1 1991 2001 3
chr1 2491 2501 2
chr1 2501 2511 1
chr1 2681 2691 3
chr1 2881 2891 4
chr1 2891 2901 1
chr1 3241 3251 6