Bash awk:在列中查找最小值和最大值

Bash awk:在列中查找最小值和最大值,bash,awk,Bash,Awk,我使用处理一个简单的.dat文件,该文件包含几行数据,每行有4列,用一个空格分隔。 我想找到第一列的最小值和最大值 数据文件如下所示: 9 30 8.58939 167.759 9 38 1.3709 164.318 10 30 6.69505 169.529 10 31 7.05698 169.425 11 30 6.03872 169.095 11 31 5.5398 167.902 12 30 3.66257 168.689 12 31 9.6747 167.049 4 30 10.760

我使用处理一个简单的.dat文件,该文件包含几行数据,每行有4列,用一个空格分隔。 我想找到第一列的最小值和最大值

数据文件如下所示:

9 30 8.58939 167.759
9 38 1.3709 164.318
10 30 6.69505 169.529
10 31 7.05698 169.425
11 30 6.03872 169.095
11 31 5.5398 167.902
12 30 3.66257 168.689
12 31 9.6747 167.049
4 30 10.7602 169.611
4 31 8.25869 169.637
5 30 7.08504 170.212
5 31 11.5508 168.409
6 31 5.57599 168.903
6 32 6.37579 168.283
7 30 11.8416 168.538
7 31 -2.70843 167.116
8 30 47.1137 126.085
8 31 4.73017 169.496
我使用的命令如下

min=`awk 'BEGIN{a=1000}{if ($1<a) a=$1 fi} END{print a}' mydata.dat`
max=`awk 'BEGIN{a=   0}{if ($1>a) a=$1 fi} END{print a}' mydata.dat`
min=`awk'BEGIN{a=1000}{if($1a)a=$1fi}END{print a}'mydata.dat`
但是,输出是min=10max=9

(类似的命令可以返回第二列的正确最小值和最大值。)

有人能告诉我哪里错了吗?谢谢大家!

Awk猜测类型

字符串“10”小于字符串“4”,因为字符“1”位于“4”之前。 使用零加法强制类型对话:

min=`awk 'BEGIN{a=1000}{if ($1<0+a) a=$1} END{print a}' mydata.dat`
max=`awk 'BEGIN{a=   0}{if ($1>0+a) a=$1} END{print a}' mydata.dat`
min=`awk'开始{a=1000}{if($10+a)a=$1}结束{print a}'mydata.dat`

您的问题很简单,您的脚本中有:

if ($1<a) a=$1 fi
如果您不喜欢NaN,请选择输入文件为空时希望打印的内容。

非awk答案:

cut -d" " -f1 file |
sort -n |
tee >(echo "min=$(head -1)") \
  > >(echo "max=$(tail -1)")
这个tee命令可能有点太聪明了。tee将其stdin流作为参数复制到文件名,并将相同的数据流传输到stdout。我使用进程替换来过滤流

可以使用相同的效果(不太夸张)提取数据流的第一行和最后一行:

cut -d" " -f1 file | sort -n | sed -n '1s/^/min=/p; $s/^/max=/p'


延迟但较短的命令,在没有初始假设的情况下更精确:

awk'(NR==1){Min=$1;Max=$1};(NR>=2){if(Min>$1)Min=$1;if(Max#minimum

#马克西蒙

#要在第2列中查找,请使用-nk2,2

#对一个变量的赋值和使用

min_col=`cat your_data_file.dat | sort -nk3,3 | head -1 | awk '{print $3}'`

值被解释为字符串,因此结果是按字典顺序排列的最小/最大值。我明白了,我需要在awk中将字符串转换为int。谢谢!还值得考虑
awk'NR==1{max=$1+0;next}{if($1>max)max=$1;}END{print max}“
可在不同的值范围内可靠工作,并确保
max
在第一次赋值时为数值。如果文件大小不同,则在一次传递中计算min和max会有所帮助。还可以从If语句的末尾删除假“fi”,例如:
awk'BEGIN{a=1000}{If($1正确,你的方法更灵活。如果数据文件有头,你的方法可以避免头,从第一行数据开始。我明白了。你的代码加深了我的理解。谢谢!不客气。如果你刚刚开始学习awk,我推荐Arnold Robbins的《有效的awk编程》一书。我还不知道那本书之前。我会查一下。谢谢你的推荐!这是唯一一本包含所有当前awk信息的awk书,而且它的展示效果很好。它也可以在网上获得,但是作者应该为他在这本书和GNU awk上的所有工作获得报酬,这是一本很好的参考书。不要忘记“AWK编程语言”,因为它已经过时,并且没有“SED&AWK”"因为它也过时了,而且你不需要一本书来学习如何使用sed来完成你应该使用它的事情,所以书中有一半是浪费的。你能补充一些解释吗?很好的解决方案。但是我还要注意的是,
sort
对于只查找最小值和最大值来说有点太过了。我的文件有超过100万行,
sort
运行得比它慢n其他答案,因为它不必要地将所有值按顺序排列。
cut -d" " -f1 file | sort -n | { 
    read line
    echo "min=$line"
    while read line; do max=$line; done
    echo "max=$max"
}
cat your_data_file.dat | sort -nk3,3 | head -1 
                        #this fill find minumum of column 3
cat your_data_file.dat | sort -nk3,3 | tail -1
                    #this will find maximum of column 3 
min_col=`cat your_data_file.dat | sort -nk3,3 | head -1 | awk '{print $3}'`