mocou 回复于:2005-06-10 23:45:16 |
偶是找出最小值大4的数
[quote:b868ff14a7]# cat file 1 10 2 9 3 10 4 11 5 10 6 9 7 11 8 10 9 11 10 10 11 8 12 7 13 5 14 3 15 0 16 1 17 2 18 4 19 5 20 7 21 9 22 10 23 11 24 10 25 11[/quote:b868ff14a7] [code:1:b868ff14a7]结果 # ./scripts 0 18[/code:1:b868ff14a7] [code:1:b868ff14a7]# cat scripts aa=$(awk 'BEGIN{temp=0;}{if($2<temp){temp=$2;}}END{aa=$temp;print temp;}' file) bb=$(awk '/'"\<$aa\>"'/{print $1;exit}' file) cc=$(expr "$aa" + 4) dd=$(awk '$2=='"$cc"'{if (NR>="$cc")print $1;exit}' file) echo "$aa $dd"[/code:1:b868ff14a7] 很笨。。。。。左边是最小值,后边是比最小值大三的数,且在最小值之后的数。 不知道如果最小值有几个要取哪一个?偶这里都取第一个匹配滴 |
dbcat 回复于:2005-06-11 13:38:28 |
最小值:
awk '{print $2}' file | sort -n | head -1 位置: awk '{print $2}' 2 | sort -n | head -1 |xargs -i expr {} + 4 |xargs -i awk '{if($2~/{}/)print $1}' 2 |
icesummit 回复于:2005-06-11 14:32:36 |
[quote:9c42fb3fb7="dbcat"]最小值:
awk '{print $2}' file | sort -n | head -1 位置: awk '{print $2}' 2 | sort -n | head -1 |xargs -i expr {} + 4 |xargs -i awk '{if($2~/{}/)print $1}' 2[/quote:9c42fb3fb7] pfpf :!: 不过不能用~应该用== if($2=={}/) :mrgreen: |
zleil 回复于:2005-06-11 20:25:36 |
BEGIN{ i=0; j=0; min=0; b3=0;}
{ if( i == 0 ){ min = $2; i ++; }else{ if( $2 < min ){ min = $2; j = 0; }else{ if( j == 0 && $2 - min > 3){ j = 1; b3 = $2; } } } } END{ print "min=" min " b3=" b3; } 有语法错误吗? |
w123456 回复于:2005-06-13 10:01:42 |
awk '{print $2}' 2
这里的2是什么意思? |
guangzongy 回复于:2005-06-13 10:26:03 |
[code:1:304b10974d]
awk '{if (NR==1) {min=$2;dat=$0;flag=1;} if ($2<min) {min=$2;dat=$0;flag=1;} if($2>(min+2)&&flag= =1) {tag=NR;flag=0}}END{print "MIN item:"dat;print "TAG rowNo:"tag}' yourFile [/code:1:304b10974d] |
w123456 回复于:2005-06-13 10:40:49 |
新的要求:
求由最小值 恢复到80%平均值水平的时间差 数列的平均值为 7.76 7.76 * 80%=6.2 所以从最小值0 到 7 (第1次超过 6.2 ) 的时间差为 20-15=5 |
w123456 回复于:2005-06-13 10:44:28 |
dbcat icesummit
不能排序的。 排序就对时间顺序大乱了, “在最小值的后面数据,找出第一个 比最小值” 这一条件就无法实现了 |
mocou 回复于:2005-06-13 10:47:04 |
偶的行不行,看到几位前辈的贴了了,偶都汗颜了 |
guangzongy 回复于:2005-06-13 11:22:22 |
分了两步完成 :oops:
[code:1:2582d80382] #get min data and avg*80% data. result=(`awk '{if(NR==1) min=$2; if(min>$2) min=$2;sum+=$2}END{print min" "sum/NR*0.8}' yourFile`) #get the tag time. awk '{if($2=='${result[0]}') {startPos=$1;flg="true";} if(flg=="true"&&$2>'${result[1]}') {print $1-startPos;exit;}}' yourFile [/code:1:2582d80382] |
guangzongy 回复于:2005-06-13 11:27:43 |
[quote:3e7152dee9="mocou"]偶的行不行,看到几位前辈的贴了了,偶都汗颜了[/quote:3e7152dee9]
条条大路通罗马 :mrgreen: BTW:[color=red:3e7152dee9]前辈[/color:3e7152dee9] :em06: ,估计几位大侠们会被叫得走不动道的 :em06: :mrgreen: |
w123456 回复于:2005-06-13 16:22:52 |
多谢 guangzongy |
begincwcw 回复于:2005-06-13 16:26:13 |
试试这个:
cat filename: 1 10 2 9 3 10 4 11 5 10 6 9 7 11 8 10 9 11 10 10 11 8 12 7 13 5 14 3 15 0 16 1 17 2 18 4 19 5 20 7 21 9 22 10 23 11 24 10 25 11 程序如下: nawk '{ line[NR] = $2 } END{ for(i = 1; i <= NR; i++){ avg += line[i] if(m == 0) min = line[i] else if(line[i] < min){ min = line[i] x = i } m++ } for(n = x; n <= NR; n++){ if( line[n] - min > 3) break } for(n1 = x; n1 <= NR; n1++){ if( line[n1] > avg / NR * 0.8 ) break } { printf("\n\n最小值为: %s\n第一个比最小值大于3 的数据位置是: %s行\n由最小值恢复到80%平均值水平的时间差为: %s秒 \n\n\n", min, n, n1 - x) }}' filename 运行结果: 最小值为: 0 第一个比最小值大于3 的数据位置是: 18行 由最小值恢复到80%平均值水平的时间差为: 5秒 |
w123456 回复于:2005-06-13 19:49:52 |
begincwcw 你的代码好C,呵呵 |
begincwcw 回复于:2005-06-13 19:57:43 |
习惯了,w123456,我觉得你的问题很有针对性,我比较感兴趣。 |
waker 回复于:2005-06-14 09:30:27 |
[code:1:087de50c90]awk 'BEGIN{min=1000}
{ a[$2]=a[$2]" "NR;sum+=$2; if ($2<min) {min=$2;minline=NR}} END{ avg=sum/NR*0.8;sub(/\..*/,"",avg) for (;!a[avg];avg++); n=split(a[avg],b) for (j=1;j<=n;j++){if (b[j]>minline) {print "min: "min print "offset: "b[j]-minline"s";exit}}}' filename [/code:1:087de50c90] 尝试扫描一次 :mrgreen: |
begincwcw 回复于:2005-06-14 13:14:46 |
waker,我觉得你的程序中,avg取整数的话有问题,如:平均数为6.28,第二十行为7的话没问题,但二十行为6的话,你的程序就有问题,就少一秒了。你可以试试? |
wayy2008 回复于:2005-06-14 13:22:07 |
找最小值,试一下这个:
sort -k2 filename|head -1 位置嘛,就比较麻烦一点了,呵呵。 |
waker 回复于:2005-06-14 13:28:11 |
[quote:f702c8a960="begincwcw"]waker,我觉得你的程序中,avg取整数的话有问题,如:平均数为6.28,第二十行为7的话没问题,但二十行为6的话,你的程序就有问题,就少一秒了。你可以试试?[/quote:f702c8a960]
那就改改,avg+1 是不是就行了? :mrgreen: [code:1:f702c8a960] awk 'BEGIN{min=1000} { a[$2]=a[$2]" "NR;sum+=$2; if ($2<min) {min=$2;minline=NR}} END{ avg=sum/NR*0.8;sub(/\..*/,"",avg) for (;!a[++avg];); n=split(a[avg],b) for (j=1;j<=n;j++){if (b[j]>minline) {print "min: "min print "offset: "b[j]-minline"s";exit}}}' filename [/code:1:f702c8a960] |
begincwcw 回复于:2005-06-14 13:45:43 |
[quote:dea97a806e="waker"]那就改改,avg+1 是不是就行了?[/quote:dea97a806e]
如果平均数是:5.82呢? |
waker 回复于:2005-06-14 14:18:39 |
5.82和5.02有什么区别? |
waker 回复于:2005-06-14 14:27:31 |
问题会出在avg正好是整数的时候,如果一行的值正好是平均值的80%时要不要计算在内,如果要
在 sub(....)前加一句 if(avg ~/\./)avg++好了 [code:1:3382bd3db4] awk 'BEGIN{min=1000} { a[$2]=a[$2]" "NR;sum+=$2; if ($2<min) {min=$2;minline=NR}} END{ avg=sum/NR*0.8;if(avg ~/\./)avg++;sub(/\..*/,"",avg) for (;!a[avg];avg++); n=split(a[avg],b) for (j=1;j<=n;j++){if (b[j]>minline) {print "min: "min print "offset: "b[j]-minline"s";exit}}}' filename [/code:1:3382bd3db4] |
begincwcw 回复于:2005-06-14 16:47:06 |
[quote:4509b98e93="awk 'BEGIN{min=1000}
{ a[$2]=a[$2]" "NR;sum+=$2; if ($2<min) {min=$2;minline=NR}} END{ avg=sum/NR*0.8;if(avg ~/\./)avg++;sub(/\..*/,"",avg) for (;!a[avg];avg++); n=split(a[avg],b) for (j=1;j<=n;j++){if (b[j]>minline) {print "min: "min print "offset: "b[j]-minline"s";exit}}}' filename "][/quote:4509b98e93] waker,我用你的程序测试了一下,测试结果如下: cat filename 1 11 2 9 3 10 4 11 5 10 6 9 7 11 8 10 9 11 10 10 11 8 12 7 13 5 14 3 15 0 16 2 17 3 18 6 19 8 20 9 21 11 22 12 23 13 24 10 25 11 平均值:6.72 最小值为: 0 第一个比最小值大于3 的数据位置是: 18行 由最小值恢复到80%平均值水平的时间差为: 4秒 就用你上面的程序运行,但你的程序什么也没有显示。 cat filename 1 11 2 9 3 10 4 11 5 10 6 9 7 11 8 10 9 11 10 10 11 8 12 7 13 5 14 3 15 0 16 1 17 2 18 4 19 5 20 7 21 8 22 10 23 11 24 10 25 11 平均值:6.208 最小值为: 0 第一个比最小值大于3 的数据位置是: 18行 由最小值恢复到80%平均值水平的时间差为: 5秒 你的程序运行正确。 运行结果如下: min: 0 offset: 5s 以上程序在unix5.0.5下测试,你可以去试试。 |
waker 回复于:2005-06-14 21:02:48 |
awk 'BEGIN{min=1000}
{ a[$2]=a[$2]" "NR;sum+=$2; if ($2<min) {min=$2;minline=NR}} END{ avg=sum/NR*0.8;[color=red:e6a1a89ea2]if(!avg ~/\./)avg++;[/color:e6a1a89ea2]sub(/\..*/,"",avg) for (;!a[avg];avg++); n=split(a[avg],b) for (j=1;j<=n;j++){if (b[j]>minline) {print "min: "min print "offset: "b[j]-minline"s";exit}}}' filename 逻辑错误 :mrgreen: 纠正一下,多谢指正 |
waker 回复于:2005-06-15 08:30:37 |
是我的方法有问题,如果合适的值在min之前出现就会有问题 |
waker 回复于:2005-06-15 09:09:21 |
改一下
[code:1:7c25b947ce] awk 'BEGIN {min=10000} { sum+=$2; if ($2<min) {min=$2;minline=NR;delete a}a[$2]=NR} END{ avg=sum/NR*0.8; if(sub(/\..*/,"",avg)) avg++; for (;!a[avg];avg++); print "min: "min print "offset: "a[avg]-minline"s"}' filename [/code:1:7c25b947ce] |
begincwcw 回复于:2005-06-15 11:23:11 |
waker可能我的awk版本与你的版本不一样,运行时提示delete a错误。 |
waker 回复于:2005-06-15 12:33:36 |
`delete array ' 是gawk扩展
其它的版本可能是 for (i in array) delete array[i]的形式 |
begincwcw 回复于:2005-06-15 14:03:47 |
[quote:e627d27e73="waker"]delete array ' 是gawk扩展
其它的版本可能是 for (i in array) delete array[i]的形式[/quote:e627d27e73] 多谢waker。 |