【问题标题】:AWK, Create array of data in BEGIN {} blockAWK,在 BEGIN {} 块中创建数据数组
【发布时间】:2016-06-03 04:56:48
【问题描述】:

我有一个电子表格,其中每一列代表一周中的一天。列中的每个单元格都包含当天喂食的农场动物的字符串值。像这样:

Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
cow, cow, cow, cow, cow, cow, cow,
goat, goat, goat, goat, goat, goat, 
horse, horse, , horse, horse, horse, horse
 , pig, , , pig, , ,
duck, duck, duck, duck, duck, goose, duck
 , , , , , , goat

请注意,每天喂牛,每天喂山羊,但记录在两个不连贯的行上,周三不喂马,周二和周五只喂猪,而不是喂周六的鸭子,他们改为喂鹅,但记录在鸭子线上。

我现在要做的是构建一个 AWK 脚本,它会告诉我一周中的每一天都喂了哪些动物。

我想我想要做的是循环遍历数据一次,并为字段 $7 中的每个唯一值创建一个关联数组,其想法是如果动物在周日没有被喂食,它不会每次都被喂食星期几。

然后,我想再次循环遍历文件,并在找到动物的每一天递增保存动物值的数组的值。然后我想打印出每天喂食的每只动物的名字。

这是我目前得到的伪代码:

awk -F "," 'FNR > 1 BEGIN {
    [SOMEHOW MAGICALLY CONSTRUCT AN ARRAY HOLDING THE VALUES OF FIELD $7]
    }
    {
        for (i=1; i <= NR; i++) {
            if ($i in animals) {
                animals[$i]++
            }
            else {
                 animals[$i]=0
            }
         }
     }
     END {
         for (animal in animals) {
             if (animals[animal]==7) {
                 print $animal[animal]
             }
          }
     }
}

我知道 AWK 代码在很多层面上可能都不正确。但是,尽管我整天都在阅读 O'Reilly 的“sed & awk”书并参考它和 Google ,但我一整天都在努力解决这个问题。

任何帮助将不胜感激。

【问题讨论】:

  • 你说得对,如果星期天不喂动物,它就不是每天都喂。但是,如果动物在周日喂食,但在周一(或周二,或……)没有喂食,那么它仍然不是每天都喂食。所以,周日吃饱是必要条件;这不是充分条件。
  • 数据也可以有一行goose, goose, goose, goose, goose, duck, goose吗?也可以有一行goat, goat, goat, goat, goat, goat, goat 吗?这意味着(每天)喂食的山羊被记录在 3 行数据中,并且每天都会有两个山羊条目。这是一个“输入数据有多混乱”的问题。
  • 一只动物是否有可能在一天内被喂食不止一次?

标签: arrays bash awk


【解决方案1】:

我现在想做的是构建一个 AWK 脚本,它会告诉我 每周每天给哪些动物喂食。

每天只喂山羊和牛:

$ awk -F'[[:space:]]*,[[:space:]]*' 'NR>1{for (i=1;i<=7;i++) if ($i) fed[$i]+=1} END{for (a in fed) if (fed[a]==7) print a}' farmdata
goat
cow

工作原理

awk 隐式循环文件中的每条记录(行)。该脚本使用一个名为 fed 的数组来跟踪每只动物的喂食次数。

  • -F'[[:space:]]*,[[:space:]]*'

    这会将字段分隔符设置为逗号以及相邻的空格(如果有)。

  • NR&gt;1{for (i=1;i&lt;=7;i++) if ($i) fed[$i]+=1}

    对于第一行之后的每一行,循环遍历每个字段并将该字段中名称的计数加一。

  • END{for (a in fed) if (fed[a]==7) print a}

    当我们到达文件末尾后,打印出每只被喂食七次的动物。

多行

对于那些喜欢多行代码的人:

awk -F'[[:space:]]*,[[:space:]]*' '
    NR>1{
        for (i=1;i<=7;i++) 
           if ($i) fed[$i]+=1
    }  

    END{
        for (a in fed) 
           if (fed[a]==7) print a
    }
    ' farmdata

【讨论】:

  • 非常感谢!我被困在必须使用 BEGIN{} 块的想法上。
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 2019-05-06
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 2014-09-26
  • 2021-09-23
  • 2015-06-01
相关资源
最近更新 更多