AWK,在BEGIN {}块中创建数据数组

时间:2016-06-03 04:56:48

标签: arrays bash awk

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

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&amp; awk”一书并且整天都在引用它和The Googles。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

  

我现在要做的是构建一个告诉我的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>1{for (i=1;i<=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