AWK过滤给定变量的第一行和最后一行,丢弃中间行

时间:2019-04-22 10:39:39

标签: unix awk filtering

我试图通过使用AWK在制表符分隔的txt文件中选择给定变量的第一行和最后一行来过滤文件。

制表符分隔的文件如下所示:

1 apple  30
2 apple  35
3 apple  36
4 apple  20
5 pear   10
6 pear   30
7 pear   45
8 orange 16 

END 

并且我正在尝试使用awk进行处理,只打印$ 2中每个变量的第一行和最后一行(在此示例中为Fruit列)

我实际上拥有的文件的长度约为35000行,并且在我想用作过滤器的列中有3000个唯一变量(因此在上面的示例col2中)

我当时在想办法是创建一个唯一的col2值数组(苹果,梨,橙),然后使用该数组从较大的文件中提取第一个和最后一个值...但是在命名方面有些建议每个索引变量选择第一行和最后一行所需的时间将不胜感激。 :)

上面给出的INPUT文件,预期输出为

1 apple  30
4 apple  20
5 pear   10
7 pear   45
8 orange 16

输出也需要包括只有一个条目的条目(在这种情况下为橙色)

3 个答案:

答案 0 :(得分:0)

一种方法:

awk '$2!=prev{if (pline){print pline;}print;}{prev=$2;pline=$0;}END{print pline;}' file | uniq

每次遇到新的第二列行时打印。在打印新的第二列行时,如果上一行不为空,则也要打印该行。 uniq会删除在它们之间存在单个记录的情况下打印出来的重复行。

答案 1 :(得分:0)

即使给定键值的第一行和最后一行都显示相同的数据,或者该数据包含空白行或0行(假设您希望像其他所有行一样处理这些行),这也将起作用,如果没有,则可以轻松跳过):

$ cat tst.awk
$2 != prev2 {
    if ( NR > 1 ) {
        print rec
    }
    beg = rec = $0
    prev2 = $2
    next
}
{ rec = beg ORS $0 }
END { print rec }

$ awk -f tst.awk file
1 apple  30
4 apple  20
5 pear   10
7 pear   45
8 orange 16

答案 2 :(得分:0)

在gnu awk上尝试过,不需要外部程序

awk '{if($0~/^[a-z0-9]/) a[NR]=$0} END{f=1;asort(a); for(;i++<NR;){split(a[i],b);if(b[2]==$2||f){$1=b[1];$2=b[2];$3=b[3];if(f){f=0;print}} else if(b[2]){print;print b[1],($2=b[2]),b[3]}} }' d