Home > database >  Trying to sort two different columns of a text file, (one asc, one desc) in the same awk script
Trying to sort two different columns of a text file, (one asc, one desc) in the same awk script

Time:02-16

I have tried to do it separately, and I am getting the right result, but I need help to combine the two. This is the csv file:

maruti          swift       2007        50000       5
honda           city        2005        60000       3
maruti          dezire      2009        3100        6
chevy           beat        2005        33000       2
honda           city        2010        33000       6
chevy           tavera      1999        10000       4
toyota          corolla     1995        95000       2
maruti          swift       2009        4100        5
maruti          esteem      1997        98000       1
ford            ikon        1995        80000       1
honda           accord      2000        60000       2
fiat            punto       2007        45000       3

I am using this script to sort by first field:

 BEGIN { print "========Sorted Cars by Maker========"
 }
 {arr[$1]=$0} 
 END{
    PROCINFO["sorted_in"]="@val_str_desc"                       
        for(i in arr)print arr[i]
        }

I also want to run a sort on the year($3) ascending in the same script. I have tried many ways but to no avail. A little help to do that would be appreciated..

CodePudding user response:

One in GNU awk:

$ gawk '
{
    a[$1][$3][  c[$1,$3]]=$0
}
END {
    PROCINFO["sorted_in"]="@ind_str_desc"
    for(i in a) {
        PROCINFO["sorted_in"]="@ind_str_asc"
        for(j in a[i]) {
            PROCINFO["sorted_in"]="@ind_num_asc"
            for(k in a[i][j])
                print a[i][j][k]
        }
    }
}' file

Output:

toyota          corolla     1995        95000       2
maruti          esteem      1997        98000       1
maruti          swift       2007        50000       5
...

CodePudding user response:

Assumptions:

  • individual fields do not contain white space
  • primary sort: 1st field in descending order
  • secondary sort: 3rd field in ascending order
  • no additional sorting requirements provided in case there's a duplicate of 1st 3rd fields (eg, maruti 2009) so we'll maintain the input ordering

One idea using sort:

sort -k1,1r -k3,3n auto.dat

Another idea using GNU awk (for arrays of arrays and PROCINFO["sorted_in"]):

awk '
    { cars[$1][$3][n  ]=$0 }                     # "n" used to distinguish between duplicates of $1 $3
END { PROCINFO["sorted_in"]="@ind_str_desc"
      for (make in cars) {
          PROCINFO["sorted_in"]="@ind_num_asc"
          for (yr in cars[make])
              for (n in cars[make][yr])
                  print cars[make][yr][n]
      }
    }
' auto.dat

Both of these generate:

toyota          corolla     1995        95000       2
maruti          esteem      1997        98000       1
maruti          swift       2007        50000       5
maruti          dezire      2009        3100        6
maruti          swift       2009        4100        5
honda           accord      2000        60000       2
honda           city        2005        60000       3
honda           city        2010        33000       6
ford            ikon        1995        80000       1
fiat            punto       2007        45000       3
chevy           tavera      1999        10000       4
chevy           beat        2005        33000       2
  • Related