【问题标题】:Division a column in period and print min max for each in awk在期间划分一列并在 awk 中为每个列打印最小最大值
【发布时间】:2014-04-09 13:25:51
【问题描述】:

我有一个包含两列的数据文件。其中一个具有周期性变化,每个周期的最大值和最小值不同:

a     3
b     4
c     5
d     4
e     3
f     2
g     1
h     2
i     3
j     4
k     5
l     6
m     5
n     4
o     3
p     2
q     1
r     0
s     1
t     2
u     3

我们可以发现,在第 1 周期(从 a 到 i):max = 5,min = 1。在第 2 周期(从 i 到 u):max = 6,min = 0。

使用 awk,我只能打印所有第二列的最大值和最小值,但我无法在每个周期之后打印这些值最小值和最大值。这意味着我希望获得这样的结果:

period   min   max
1        1     5
2        0     6

这就是我所做的:

{
nb_lignes = 21
period = 9
nb_periodes = int(nb_lignes/period)
}

{
for (j = 0; j <= nb_periodes; j++)
   {   if (NR == (1 + period*j)) {{max=$2 ; min=$2}}
       for (i = (period*j); i <= (period*(j+1)); i++)
           {
               if (NR == i) 
                  { 
                     if ($2 >= max) {max = $2} 
                     if ($2 <= min) {min = $2} 
                     {print "Min: "min,"Max: "max,"Ligne: " NR}
                  }
           }
   }
}
#END { print "Min: "min,"Max: "max }

但结果与我搜索的结果相去甚远:

Min: 3 Max: 3 Ligne: 1
Min: 3 Max: 4 Ligne: 2
Min: 3 Max: 5 Ligne: 3
Min: 3 Max: 5 Ligne: 4
Min: 3 Max: 5 Ligne: 5
Min: 2 Max: 5 Ligne: 6
Min: 1 Max: 5 Ligne: 7
Min: 1 Max: 5 Ligne: 8
Min: 1 Max: 5 Ligne: 9
Min: 1 Max: 5 Ligne: 9
Min: 4 Max: 4 Ligne: 10
Min: 4 Max: 5 Ligne: 11
Min: 4 Max: 6 Ligne: 12
Min: 4 Max: 6 Ligne: 13
Min: 4 Max: 6 Ligne: 14
Min: 3 Max: 6 Ligne: 15
Min: 2 Max: 6 Ligne: 16
Min: 1 Max: 6 Ligne: 17
Min: 0 Max: 6 Ligne: 18
Min: 0 Max: 6 Ligne: 18
Min: 1 Max: 1 Ligne: 19
Min: 1 Max: 2 Ligne: 20
Min: 1 Max: 3 Ligne: 21

提前感谢您的帮助。

【问题讨论】:

  • 每个周期的长度是如何确定的?
  • 我们可以将 9 视为周期,每次我们有一个最大值和一分钟

标签: awk max min period


【解决方案1】:

尝试类似:

$ awk '
BEGIN{print "period", "min", "max"}
!f{min=$2; max=$2; ++f; next}
{max = ($2>max)?$2:max; min = ($2<min)?$2:min; f++}
f==9{print ++a, min, max; f=0}' file
period min max
1 1 5
2 0 6
  • 如果未设置标志f,则将第二列分配给最大和最小变量并开始增加标志。
  • 对于每一行,检查第二列。如果它大于我们的 max 变量,则将该列分配给 max。同样,如果它小于我们的 min 变量,则将其分配给我们的 min 变量。继续增加标志。
  • 一旦标志达到 9,打印周期数、最小值和最大值变量。将标志重置为 0 并从下一行重新开始。

【讨论】:

  • 这就是我希望获得的输出文件。谢谢 ! :)
【解决方案2】:

我已经开始了,所以我会完成。我选择创建一个包含每个周期的最小值和最大值的数组:

awk -v period=9 '
BEGIN { print "period", "min", "max" } 
NR % period == 1 { ++i } 
!min[i] || $2 < min[i] { min[i] = $2 } 
$2 > max[i] { max[i] = $2 } 
END { for (i in min) print i, min[i], max[i] }' input

索引i 每增加period 行数(在本例中为9)。如果尚未设置任何值或找到新的最小值/最大值,请更新数组。

编辑:如果尚未设置max[i],则为$2 &gt; max[i],因此无需检查!max[i]。

【讨论】:

  • 太有趣了,我开始(但在我的情况下没有完成)几乎相同。只是我用它来设置最小值和最大值:max[var] = max[var] &lt; $2 ? $2 : max[var]; min[var]= (min[var] &amp;&amp; min[var]&lt;$2) ? min[var] : $2
  • @fedorqui 感谢您的意见。看着你的,我意识到我的!max[i],虽然很适合对称,是多余的。我想我会删除它。我发现我的方法稍微清晰一些,但话又说回来,我可能有偏见;)
【解决方案3】:
awk 'BEGIN{print "Period","min","max"}
     NR==1||(NR%10==0){mi=ma=$2}
     {$2<mi?mi=$2:0;$2>ma?ma=$2:0}
     NR%9==0{print ++i,mi,ma}' your_file

测试员here

【讨论】:

    猜你喜欢
    • 2018-09-05
    • 1970-01-01
    • 2020-06-08
    • 2015-06-29
    • 1970-01-01
    • 2016-09-28
    • 2012-01-16
    相关资源
    最近更新 更多