您好我有这个文本文件:
chr1 30.3
chrx 30.5
chr3 31.3
chr4 31.7
chrX 33.6
chr1 34.1
我想得到:
30 - 31 2
31 - 32 2
32 - 33 0
33 - 34 1
34 - 35 1
我正在尝试使用这个bash和awk代码,但它不起作用。你能帮帮我吗?
#!/bin/bash
for i in {30..60..1}
do
h=$i
let "h += 1"
export i
export h
awk -v g=$i -v c=$h '{if ($3 >= $g && $3< $c) print $0}' /home/filip/Desktop/AMrtin\ Hynek/doktor.txt | awk 'END{print $i"-"$h,"\t",NR}'
done
答案 0 :(得分:5)
这可以是一种方式:
awk '{d=int($2)
a[d]++
if (NR==1) {min=d}
min=(min>=d?d:min)
max=(max>d?max:d)}
END{for (i=min; i<=max; i++) print i, "-", i+1, a[i]+0}' file
跟踪数组a[]
中的外观,然后在min
和max
之间循环索引。
d=int($2)
获取数字的整数部分。a[d]++
增加数组上此字段的出现次数。if (NR==1) {min=d}
在第一行设置最小值。min=(min>=d?d:min)
更新最低要求。max=(max>d?max:d)}
更新最大值。END{for (i=min; i<=max; i++) print i, "-", i+1, a[i]+0}
遍历打印外观的索引。如果未找到任何值,则根据+0
技巧(thanks Jaypal!)打印0。$ awk '{d=int($2); a[d]++; if (NR==1) {min=d}; min=(min>=d?d:min); max=(max>d?max:d)} END{for (i=min; i<=max; i++) print i, "-", i+1, a[i]+0}' file
30 - 31 2
31 - 32 2
32 - 33 0
33 - 34 1
34 - 35 1
答案 1 :(得分:4)
Perl解决方案:
perl -ane '
$h{ int $F[1] }++
}{
print "$_ - ", $_ + 1, "\t", $h{$_}, "\n"
for sort { $a <=> $b } keys %h
'
要获得零线,您可以从List::Util添加min
和max
:
perl -MList::Util=min,max -ane '
$h{ int $F[1] }++
}{
print "$_ - ", $_ + 1, "\t", 0 + $h{$_}, "\n"
for min(keys %h) .. max(keys %h);
'
答案 2 :(得分:1)
我的解决方案:
awk '{print $2}' file.txt | sed 's/\..*//' | sort | uniq -c | awk '{print $2, $1}' > counts.txt
paste <(seq 30 34) <(seq 31 35) | join -a1 - counts.txt | awk '!$3{$3=0}{print $1 "-" $2 " " $3}'