我有一个文件名数字,只包含一堆随机数
1 2 3
7 5 9
2 2 9
5 4 5
7 2 6
我必须创建一个脚本来查找每行的中位数,这是我的代码:
while read -a row
do
for i in "${row[@]}"
do
length=`expr ${#row[@]} % 2`
if [ $length -ne 0 ] ; then
mid=`expr ${#row[@]} / 2`
echo ${row[middle]}
elif [ $length -eq 0 ] ; then
val1=`expr ${#row[@]} / 2`
val2=`expr (${$row[@]} / 2) + 1`
mid=`expr ($val1 + $val2) / 2`
echo $mid
done | sort -n
done < numbers
但是这不起作用,而是显示错误。我在这段代码中犯了什么错误?另外我还没弄清楚放置sort -n
的正确方法在哪里,因为在计算中位数之前需要先对它进行排序,对吗?
答案 0 :(得分:1)
Bash只能进行整数运算,你需要像bc
这样的工具来计算平均值:
#!/bin/bash
while read -a n ; do
n=($(IFS=$'\n' ; echo "${n[*]}" | sort -n))
len=${#n[@]}
if (( len % 2 )) ; then
echo ${n[ len / 2 ]}
else
bc -l <<< "scale=1; (${n[ len / 2 - 1 ]} + ${n[ len / 2 ]}) / 2"
fi
done
我可能会找到更高级别的语言,例如的Perl:
#!/usr/bin/perl
use warnings;
use strict;
while (<>) {
my @n = sort { $a <=> $b } split;
print @n % 2 ? $n[ @n / 2 ]
: ($n[ @n / 2 - 1 ] + $n[ @n / 2 ]) / 2,
"\n";
}
答案 1 :(得分:0)
我只是为了它的乐趣而不得不放弃它。
请注意,我不使用if
,而是使用一小部分索引。
awk '{
split($0,a) # create array a from input line
asort(a,b) # sort array into array b (gnu awk specific)
# add twice the median, or around the median and divide by 2
print ( b[int(NF/2+0.7)] + b[int(NF/2+1.2)] )/2
}' numbers
缩短(67个字符):
awk '{split($0,a);asort(a,b);print(b[int(NF/2+0.7)]+b[int(NF/2+1.2)])/2}' numbers
66 prs golf: - )
awk '{split($0,a);asort(a,b);$0=(b[int(NF/2+0.7)]+b[int(NF/2+1.2)])/2}1' numbers