阅读专栏和查找中位数(Bash)

时间:2015-10-13 06:36:43

标签: bash median

我想找到每列的中位数,但它并不像我想要的那样工作。

RadioButton

我期待

1 2 3 
3 2 1
2 1 5

结果,然而事实证明它只是给出总和错误和一些"总和"列。以下是#34;

列中"中位数代码的片段
2 2 3

注意:我想练习bash,这就是我使用bash进行硬编码的原因。 如果有人能帮助我,我真的很感激,特别是在BASH。谢谢。

1 个答案:

答案 0 :(得分:3)

Bash实际上不适合这样的低级文本处理:read命令对它读取的每个字符进行系统调用,这意味着它很慢,而且它是一头CPU猪。它可以处理交互式输入,但将其用于一般文本处理是疯狂的。为此使用awk(Python,Perl等)要好得多。

作为学习Bash的练习我没关系,但请尽量避免在实际程序中使用read进行批量文本处理。有关详细信息,请参阅Unix& amp;上的Why is using a shell loop to process text considered bad practice?。 Linux Stack Exchange网站,特别是写的答案 StéphaneChazelas(Shellshock Bash bug的发现者)。

无论如何,回到你的问题......:)

您的大部分代码都可以,但

result=${column[*]} | sort -n

没有按你的意愿行事。

这是使用纯Bash获取列中位数的一种方法:

#!/usr/bin/env bash

# Find medians of columns of numeric data
# See http://stackoverflow.com/q/33095764/4014959
# Written by PM 2Ring 2015.10.13

fname=$1
echo "input data:"
cat "$fname"
echo

#Read rows, saving into columns
numrows=1
while read -r -a array; do
    ((numrows++))
    for i in "${!array[@]}"; do
        #Separate column items with a newline
        column[i]+="${array[i]}"$'\n'
    done
done < "$fname"

#Calculate line number of middle value; which must be 1-based to use as `head`
#argument, and must compensate for extra newline added by 'here' string, `<<<`
midrow=$((1+numrows/2))
echo "midrow: $midrow"

#Get median of each column
result=''
for i in "${!column[@]}"; do
    median=$(sort -n <<<"${column[i]}" | head -n "$midrow" | tail -n 1)
    result+="$median "
done

echo "result: $result" 

<强>输出

input data:
1 2 3
3 2 1
2 1 5

midrow: 3
result: 2 2 3