awk 'BEGIN{print "Pricerange\tpricerangecount"}
NR>1 {cur=int($0/10000); A[cur]+=1; if (cur>m) m=cur; }
END {for(i=0;i<=m;i++) printf("%d-%d:\t%d\n",i*10000, (i+1)*10000, A[i])}'
Eu tenho um arquivo de texto delimitado por tabulação, com cerca de 3 mil linhas.
Eu quero calcular a frequência dos dados que aparecem nele, em 10.000 intervalos.
Input.txt
Price
500
1500
10001
15000
17000
25000
33000
39000
:
:
8000000
Output.txt
Pricerange pricerangecount
0-10000 2
10000-20000 3
20000-30000 1
30000-40000 2
:
:
Eu geralmente uso gsl-histogram
do pacote Biblioteca Científica GNU . Como uma linha no seu caso (sem impressão bonita, as soluções anteriores estão bem, e eu as inventei):
tail -n+2 Input.txt | gsl-histogram 0 40000 4
Perl:
perl -ne'$h{int$_/10000}++;END{printf"%d0000-%d0000 %d\n",$_,$_+1,$h{$_}for sort{$a<=>$b}keys%h}'
expandido:
while(<>) { #read each line (-n)
$h{int $_/10000}++; #count buckets
}
for (sort {$a<=>$b} keys %h) { #sort numerically
printf "%d0000-%d0000 %d\n", $_, $_+1, $h{$_};
}
Aqui está uma alternativa de coreutils e dc:
<Input.txt tail -n +2 | while read; do <<< "$REPLY 10000 /p" | dc; done | sort -n | uniq -c \
| while read cnt rng; do
printf "%-15s %-15s\n" \
$(<<< "$rng 10000 *p" | dc)-$(<<< "$rng 1 + 10000 *p" | dc) $cnt
done > Output.txt
Output.txt:
0-10000 2
10000-20000 3
20000-30000 1
30000-40000 2
Embora o bash não seja uma boa solução, após um comentário, aqui outra solução
N=10000
while read n;do [[ $n =~ ^[0-9]*$ ]]&&((a[n/N]++));done
for i in ${!a[*]};do echo $((i*N))-$(((i+1)*N-1)) $((a[i]));done
será mais rápido em arquivos pequenos, porque não há a sobrecarga de gerar um novo processo, mas menos eficiente em arquivos grandes.