我使用 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.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 = 10 且 max = 9 。
(类似的命令可以返回第二列的正确最小值和最大值。)
有人能告诉我哪里错了吗?谢谢!
答案 0 :(得分:8)
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`
答案 1 :(得分:4)
非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'
或
cut -d" " -f1 file | sort -n | {
read line
echo "min=$line"
while read line; do max=$line; done
echo "max=$max"
}
答案 2 :(得分:3)
您的问题只是在您的脚本中有:
if ($1<a) a=$1 fi
并且最终fi
不是awk语法的一部分,所以它被视为一个变量,因此a=$1 fi
是字符串连接,所以你告诉awk a
包含一个字符串,而不是一个数字,因此字符串比较而不是$1<a
中的数字。
更重要的是,一般来说,永远不要从最大/分钟的某个猜测值开始,只需使用读取的第一个值作为种子。这是编写脚本的正确方法:
$ cat tst.awk
BEGIN { min = max = "NaN" }
{
min = (NR==1 || $1<min ? $1 : min)
max = (NR==1 || $1>max ? $1 : max)
}
END { print min, max }
$ awk -f tst.awk file
4 12
$ awk -f tst.awk /dev/null
NaN NaN
$ a=( $( awk -f tst.awk file ) )
$ echo "${a[0]}"
4
$ echo "${a[1]}"
12
如果您不喜欢NaN
选择输入文件为空时您想要打印的内容。
答案 3 :(得分:1)
后期但命令更短且精度更高,无需初始假设:
awk '(NR==1){Min=$1;Max=$1};(NR>=2){if(Min>$1) Min=$1;if(Max<$1) Max=$1} END {printf "The Min is %d ,Max is %d",Min,Max}' FileName.dat
答案 4 :(得分:0)
#最少
cat your_data_file.dat | sort -nk3,3 | head -1
#this fill find minumum of column 3
#maximun
cat your_data_file.dat | sort -nk3,3 | tail -1
#this will find maximum of column 3
#要在第 2 列中查找,请使用 -nk2,2
#assing 到一个变量并使用
min_col=`cat your_data_file.dat | sort -nk3,3 | head -1 | awk '{print $3}'`