Sorting 数值和字符串值的多级排序

Sorting 数值和字符串值的多级排序,sorting,awk,Sorting,Awk,我想对如下数据使用awk对浮点值进行多级排序: store:LA----------------400.68 ----pens----------------200.34 --------reynolds--------110.34 --------butterflow------90.00 --------trimex----------NA ----copies--------------110.34 --------classmate-------110.34

我想对如下数据使用
awk
对浮点值进行多级排序:

store:LA----------------400.68  
----pens----------------200.34  
--------reynolds--------110.34  
--------butterflow------90.00  
--------trimex----------NA  
----copies--------------110.34  
--------classmate-------110.34  
----pencil--------------90.00  
--------HB--------------44.5  
--------classmate-------45.5  
数值是可用库存量

排序结果应如下所示:

store:LA----------------400.68  
----pencil--------------90.00 
--------HB--------------44.5  
--------classmate-------45.5  
----copies--------------110.34  
--------classmate-------110.34  
----pens----------------200.34  
--------butterflow------90.00  
--------reynolds--------110.34  
--------trimex----------NA  
首先根据产品按升序排列,然后根据品牌按升序排列,最后是
NA

我尝试先从商店(因为有多家商店)中提取
$2
的值,然后在商店值之后添加产品值,最后添加品牌值,并将其存储在一个数组中。
它看起来像:

400.68
400.68:200.34
400.68:200.34:110.34
400.68:200.34:90.00
400.68:200.34:NA
在此阵列上使用
asort
不会显示所需结果:

{
      match($0, /^ */);
      offset = RLENGTH;
      if (offset == 1) { items[NR] = $2 }
      else if (offset > prev_ofst) { items[NR] = items[NR-1]":"$2 } 

      else if (offset < prev_ofst) {
         prev_item = items[NR-1];
         gsub("(\\:[^:]+\\:[^:]+)$", "", prev_item);
         items[NR] = prev_item":"$2;
      }
      else {
         prev_item = items[NR-1];
         gsub("(\\:[^:]+)$", "", prev_item);
         items[NR] = prev_item" "$2;
      }
      prev_ofst = offset;
      print items[NR];
}

END{
      asort(items);
      for (i = 1; i <= NR; i++) {
          gsub("[^:]+\\:", "", items[i]);
          print items[i];
      }
}
{
匹配($0,/^*/);
偏移量=长度;
如果(偏移量==1){items[NR]=$2}
else如果(offset>prev_of st){items[NR]=items[NR-1]:“$2}
否则如果(偏移量<上一个偏移量){
上一个项目=项目[NR-1];
gsub(“(\\:[^:::+\\:[^::+)$”,“,上一项);
项目[NR]=上一个项目“$2;
}
否则{
上一个项目=项目[NR-1];
gsub(“(\\:[^::]+)$,”,上一项);
项目[编号]=上一个项目“$2;
}
prev_of st=偏移量;
印刷品[NR];
}
结束{
asort(项目);

对于(i=1;i不清楚基于最后一个NA值品牌的产品中的
是什么意思。
的意思是(您是基于样本输入中没有NA值的品牌进行排序,还是基于每行末尾有NA值的数字进行排序?),但假设您有“铅笔”和“副本”在您发布的预期输出中,以错误的顺序,这里有一种方法可以实现我认为您可能希望使用GNU awk(您已经在
asort()
)进行多维数组排序的目的:

$ cat tst.awk
match($0,/^(-*)([^-]+)(-+)([^-]+)/,a) {
    offset = length(a[1])/4 + 1
    for (i=offset+1; i<=3; i++) {
        tags[i] = ""
    }
    tags[offset] = a[2]
    vals[tags[1]][tags[2]][tags[3]] = $0
}
END {
    PROCINFO["sorted_in"] = "@ind_str_asc"
    for ( tag1 in vals ) {
        for ( tag2 in vals[tag1] ) {
            for ( tag3 in vals[tag1][tag2] ) {
                print vals[tag1][tag2][tag3]
            }
        }
    }
}

$ awk -f tst.awk file
store:LA----------------400.68
----copies--------------110.34
--------classmate-------110.34
----pencil--------------90.00
--------HB--------------44.5
--------classmate-------45.5
----pens----------------200.34
--------butterflow------90.00
--------reynolds--------110.34
--------trimex----------NA
$cat tst.awk
匹配($0,/^(-*)([^-]+)([^-]+)([^-]+)/,a){
偏移量=长度(a[1])/4+1

对于(i=offset+1;i谢谢你。数值是各个品牌的产品数量。NA表示品牌不可用,因此应在最后。同样,由于要按递增顺序排序,铅笔应在复印件之前,然后是钢笔。铅笔中HB应在同学之前,因为数值较小(根据您的回答)。此外,还有多个商店添加了第三级排序。