sort by column

wayne.lydecker at l-3com.com wayne.lydecker at l-3com.com
Wed Nov 15 22:43:05 CET 2006


Tony Balinski wrote:
> Quoting wayne.lydecker at l-3com.com:
> 
>> Nedit has a neat feature that allow me to sort a column.  What
>> I'd like to be able to do is sort BY column.  That is, highlight
>> a column (e.g. numbers) and have the lines sorted based on the
>> values in the column.  It's amazing how often I need a feature
>> like that.  Is there a macro that does this?
> 
> If you want to use string sort, here's a cheap-n-nasty way to do it
> without invoking the sort command:
> 
> Sort lines by column:
> 
> sel_start = $selection_start
> sel_end   = $selection_end
> sel_left  = $selection_left
> sel_right = $selection_right
> 
> sel_ok = (sel_start > 0)
> 
> # no selection? take whole file
> if (sel_start < 0)
>   {
>   sel_start = 0
>   sel_end   = $text_length
>   }
> 
> # lines to sort
> lines = get_range(sel_start, sel_end)
> 
> # keys to sort by
> if (sel_left >= 0)
>   keys = get_selection() # use rectangular selection content
> else
>   keys = lines
> 
> keysA  = split(keys, "\n")
> linesA = split(lines, "\n")
> 
> sorted = $empty_array
> rep_ct = $empty_array
> pad = replace_in_string(keysA[], ".", " ", "regex")
> padlen = length(pad)
> 
> # construct unique key for each line by adding a repeat count, then adding
> # the line to the sorted[] array using this key
> # (the repeat count is right justified to preserve original input order
> # among repeat occurrences of the key)
> for (i = 0; i in keysA; ++i)
>   {
>   key = keysA[i]
>   if (!(key in rep_ct))
>     count = 0
>   else
>     count = rep_ct[key]
>   ++count
>   rep_ct[key] = count
>   scount = pad count
>   len = length(scount)
>   scount = substring(scount, len - padlen, len)
>   sorted[key "\n" scount] = linesA[i]
>   }
> 
> # read out the sorted array into lines
> lines = ""
> sep = ""
> for (key in sorted)
>   {
>   lines = lines sep sorted[key]
>   sep = "\n"
>   }
> 
> # put it back in the document
> replace_range(sel_start, sel_end, lines)
> # put back selection
> if (sel_ok)
>   {
>   if (sel_left < 0)
>     select(sel_start, sel_end)
>   else
>     select_rectangle(sel_start, sel_end, sel_left, sel_right)
>   }

This works so awesome.  Thanks Tony.

-- Wayne.


More information about the Discuss mailing list