sorting - How to find the X lowest values in a list with bash/awk? -


ok problem is, have list n given lines, this:

4.96035894  2.94014535  9.71651378 on 8.37470259  9.08139103 10.23145322 off 5.73085411  4.21656546  9.98718707 on 6.40892867  9.44195654  8.83707549 on 4.26065784  3.74966832  7.89520829 on 8.89601431  9.84208918  9.63054539 on 9.10538764  8.58408119 10.87454882 on 6.21494725  4.61164407  9.08378204 off 7.62256424  9.59449339 10.84506558 off 6.49210768  4.03768151 10.75221925 off 5.04079861  4.99362253 10.34349177 off ... 

the objective find x (x < n) lines lowest value in third field (it extended given field, let's focus on third) , change fourth field (which string) on/off depending of argument called user, i.e. if argument on change on , if off change off.

in above example if instance wanted change off 3 rows lowest third value, output be:

4.96035894  2.94014535  9.71651378 on 8.37470259  9.08139103 10.23145322 off 5.73085411  4.21656546  9.98718707 on 6.40892867  9.44195654  8.83707549 off // row changed 4.26065784  3.74966832  7.89520829 off // row changed 8.89601431  9.84208918  9.63054539 on 9.10538764  8.58408119 10.87454882 on 6.21494725  4.61164407  9.08378204 off // row changed 7.62256424  9.59449339 10.84506558 off 6.49210768  4.03768151 10.75221925 off 5.04079861  4.99362253 10.34349177 off ... 

i think specific case of x=1, lowest-value row, don't know how extend arbitrary x. maybe x-sized array filling , being edited while going through list?

interesting problem, need clever arrays this:

begin {     if (!x)                           # if x wasn't set using -v default 3         x=3     if (!field)                       # if field wasn't set using -v default 3         field=3 } {     lines[nr]=$0                                    # store each line in array     sort[nr]=$field                                 # store field in array     field_a[$field]=$0                              # line lookup on field  } end{     asort(sort)                                     # sort fields        (j=1;j<=nr;j++) {                           # every line in file         for(i=1;i<=x;i++) {                         # top x values             if (lines[j] == field_a[sort[i]]) {     # if current line in top x                 sub(/on/,"off",lines[j])            # subsitution                 break                               # grab next line             }         }         print lines[j]                              # print line     } } 

save file such script.awk , run like:

$ awk -f script.awk file 4.96035894  2.94014535  9.71651378 on 8.37470259  9.08139103 10.23145322 off 5.73085411  4.21656546  9.98718707 on 6.40892867  9.44195654  8.83707549 off 4.26065784  3.74966832  7.89520829 off 8.89601431  9.84208918  9.63054539 on 9.10538764  8.58408119 10.87454882 on 6.21494725  4.61164407  9.08378204 off 7.62256424  9.59449339 10.84506558 off 6.49210768  4.03768151 10.75221925 off 5.04079861  4.99362253 10.34349177 off 

by default turns off lowest 3 values in field 3 can specify both field , number of values using -v option. instances lets turn off lowest 10 values in field 3 leaving maximum value turned on:

$ awk -v x=10 -f script.awk file 4.96035894  2.94014535  9.71651378 off 8.37470259  9.08139103 10.23145322 off 5.73085411  4.21656546  9.98718707 off 6.40892867  9.44195654  8.83707549 off 4.26065784  3.74966832  7.89520829 off 8.89601431  9.84208918  9.63054539 off 9.10538764  8.58408119 10.87454882 on 6.21494725  4.61164407  9.08378204 off 7.62256424  9.59449339 10.84506558 off 6.49210768  4.03768151 10.75221925 off 5.04079861  4.99362253 10.34349177 off 

how maximum field 2:

$ awk -v x=10 -v field=2 -f script.awk file 4.96035894  2.94014535  9.71651378 off 8.37470259  9.08139103 10.23145322 off 5.73085411  4.21656546  9.98718707 off 6.40892867  9.44195654  8.83707549 off 4.26065784  3.74966832  7.89520829 off 8.89601431  9.84208918  9.63054539 on 9.10538764  8.58408119 10.87454882 off 6.21494725  4.61164407  9.08378204 off 7.62256424  9.59449339 10.84506558 off 6.49210768  4.03768151 10.75221925 off 5.04079861  4.99362253 10.34349177 off 

note: use of asort() function requires gnu awk.


Comments

Popular posts from this blog

Perl - how to grep a block of text from a file -

delphi - How to remove all the grips on a coolbar if I have several coolbands? -

javascript - Animating array of divs; only the final element is modified -