awk:根据给定列的前 3 个不同值选择行

awk: Selecting rows based on the first 3 different values of a given column

我想阅读 fileIn.txt(逗号分隔)并仅输出 fileOut.txt 行匹配给定列的前 3 个不同值。例如,我的输入文件如下所示:

fileIn.txt
#location,day,time
home,mon,01:00
office,mon,06:00
home,mon,10:00
office,tues,03:00
home,wed,08:00
home,wed,11:00
home,thurs,02:00
home,fri,01:00
diner,fri,07:00
party,fri,09:00
home,sat,02:00
mall,sat,06:00
home,sat,09:00
beach,sun,01:00

我只想 select 前 3 天不同的行,因此我的输出文件如下所示:

fileOut.txt
#location,day,time
home,mon,01:00
office,mon,06:00
home,mon,10:00
office,tues,03:00
home,wed,08:00
home,wed,11:00

你的问题有点令人费解。但是,如果我理解正确的话,您想打印出一周中的某一天与脚本在文件中找到的前 3 个不同值之一匹配的任何行。你可以像这样用 awk 做到这一点

BEGIN { FS="," }

{
    if(dayCount < 3 && !( in days)) { days[] = 1; ++dayCount }
    if ( in days) { print }
}

awk 救援! 包括更惯用形式的 header。

$ awk -F, 'NR==1{c[]} length(c)<4{c[]}  in c' file

#location,day,time
home,mon,01:00
office,mon,06:00
home,mon,10:00
office,tues,03:00
home,wed,08:00
home,wed,11:00

解释: 第一个块用第一行值初始化数组,因为在初始化之前无法检查数组的长度。数组 c 包含不同的 $2 字段,我们不断添加直到第二个块中的大小达到 4(也就是说,header 将有 4 个不同的值)。在最后一个块中,检查该行是否是不同值之一并打印(作为默认操作)。

我不想让它更神秘,但你可以合并前两个块,因为操作是相同的

$ awk -F, 'NR==1 || length(c)<4 {c[]}  in c' file

这取决于短路逻辑运算,直到为 NR==1 初始化后才计算长度。

awk -F, '
    /^#/            {print; next}   # keep comments
    ++seen[] == 1 {count++}       # incr counter the first time value is seen
    count > 3       {exit}          # quit if we have seen 4 values
                    {print}         # otherwise print this line
' file