我想找到每列的中位数,但它并不像我想要的那样工作。
RadioButton
我期待
1 2 3
3 2 1
2 1 5
结果,然而事实证明它只是给出总和错误和一些"总和"列。以下是#34;
列中"中位数代码的片段2 2 3
注意:我想练习bash,这就是我使用bash进行硬编码的原因。 如果有人能帮助我,我真的很感激,特别是在BASH。谢谢。
答案 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