awk首先打印(第N行)每个类别的三个最小值

时间:2017-08-16 11:21:48

标签: awk

希望根据每个类别的 first three minimum values 组合打印$1 and $3。输入文件没有按任何顺序排序。 寻找你的建议。

INPUT.TXT

Country,Desc,Amount,Details
Abc,xxx,20,aaa
Abc,yyy,10,aaa
ghi,ttt,25,ccc
Abc,zzz,5,aaa
def,xxx,30,bbb
Abc,ttt,15,aaa
def,yyy,20,bbb
ghi,yyy,25,ccc
def,zzz,30,bbb
ghi,xxx,35,ccc
ghi,zzz,50,ccc
def,zzz,45,bbb

想要打印输出以及标题行NR==1 , {print}

Desired Output.txt

Country,Desc,Amount,Details
Abc,zzz,5,aaa
Abc,yyy,10,aaa
Abc,ttt,15,aaa
def,yyy,20,bbb
def,xxx,30,bbb
def,zzz,30,bbb
ghi,ttt,25,ccc
ghi,yyy,25,ccc
ghi,xxx,35,ccc

3 个答案:

答案 0 :(得分:1)

我先sort然后输入awk来选择前3行:

sort -t, -k1,1 -k3,3n file|awk -F, 'c!=$1{p=1;c=$1}p++<=3'

示例:

kent$  cat f
Abc,xxx,20,aaa
Abc,yyy,10,aaa
ghi,ttt,25,ccc
Abc,zzz,5,aaa
def,xxx,30,bbb
Abc,ttt,15,aaa
def,yyy,20,bbb
ghi,yyy,25,ccc
def,zzz,30,bbb
ghi,xxx,35,ccc
ghi,zzz,50,ccc
def,zzz,45,bbb

kent$  sort -t, -k1,1 -k3,3n f|awk -F, 'c!=$1{p=1;c=$1}p++<=3'
Abc,zzz,5,aaa
Abc,yyy,10,aaa
Abc,ttt,15,aaa
def,yyy,20,bbb
def,xxx,30,bbb
def,zzz,30,bbb
ghi,ttt,25,ccc
ghi,yyy,25,ccc
ghi,xxx,35,ccc

您可以将<=3部分更改为所需的数字,也可以将shell变量传递给awk以替换硬编码的3

更新标题行

如果您想将标题行添加到输出顶部,请快速添加head -1 file;head -1 file &&到该行

head -1 file; sort.. <(tail -n +2 file)|awk...

如果您想重定向到某个文件:(例如result

head -1 file > result; sort ....<(tail -n +2 file)|awk ... >> result

答案 1 :(得分:1)

另一个 排序 + awk 解决方案:

head -1 file && sort -t, -k1,1 -k3,3h <(tail -n +2 file) | awk -F, 'a[$1]++<3' 

输出:

Country,Desc,Amount,Details
Abc,zzz,5,aaa
Abc,yyy,10,aaa
Abc,ttt,15,aaa
def,yyy,20,bbb
def,xxx,30,bbb
def,zzz,30,bbb
ghi,ttt,25,ccc
ghi,yyy,25,ccc
ghi,xxx,35,ccc

答案 2 :(得分:1)

def category(reguest, slug):
    category = Category.objects.get(slug=slug)
    post = Post.objects.filter(category=category)
    html = 'category.html'
    context = {
    'category': category,
    'post': post,
    }
    return render(reguest, html, context)

def listofposts(request):
    query_set_list = Post.objects.all()
    context = {
    "list" : query_set_list,
    }
    html = 'base.html'
    return render(request, html, context)

第一个$ awk '{print (NR==1?1:2)","$0}' file | sort -t, -s -k1,1n -k2,2 -k4,4n | cut -d, -f2- | awk -F, 'cnt[$1]++<3' Country,Desc,Amount,Details Abc,zzz,5,aaa Abc,yyy,10,aaa Abc,ttt,15,aaa def,yyy,20,bbb def,xxx,30,bbb def,zzz,30,bbb ghi,ttt,25,ccc ghi,yyy,25,ccc ghi,xxx,35,ccc 为标题行添加1,为每隔一行添加2,以便后续awk首先保留标题行,然后sort删除前添加的值最终cut对原始数据进行操作(现已排序)。

上述方法与单独的head + tail命令的主要好处是,即使输入来自管道而不是文件,您也可以运行上述方法,因为您不必打开输入两次使用2个单独的命令。

通过上述方法,整个输入文件被输入到最终的awk命令,因此您可以按照您的预期添加/删除/修改字段等。要使用其中一个head + tail方法获得相同的行为,您需要将最终管道之前的部件分组到awk中的awk,例如:

{ }

我使用{ head -1 file && tail -n +2 file | sort -t, -s -k1,1 -k3,3h; } | awk -F, 'cnt[$1]++<3' 进行&#34;稳定排序&#34; arg to sort,顺便说一句,这样相同的$ 1和$ 3值的输入行保证按原始顺序出现。