Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort files numerically from linux command line

Okay, now this is more a rant about Linux than a question, but maybe someone knows how to do what I want. I know this can be achieved using the sort command, but I want a better solution because getting that to work is about as easy as writing a C program to do the same thing.

I have files, for arguments sake, lets say I have these files: (my files are the same I just have many more)

  • file-10.xml
  • file-20.xml
  • file-100.xml
  • file-k10.xml
  • file-k20.xml
  • file-k100.xml
  • file-M10.xml
  • file-M20.xml
  • file-M100.xml

Now this turns out to be the order I want them sorted in. Incidentally, this is the order in Windows that they are by default sorted into. That's nice. Windows groups consecutive numerical characters into one effective character which sorts alphabetically before letters.

If I type ls at the linux command line, I get the following garbage. Notice the 20 is displaced. This is a bigger deal when I have hundreds of these files that I want to view in a report, in order.

  • file-100.xml
  • file-10.xml
  • file-20.xml
  • file-k100.xml
  • file-k10.xml
  • file-k20.xml
  • file-M100.xml
  • file-M10.xml
  • file-M20.xml

I can use ls -1 | sort -n -k 1.6 to get the ones without 'k' or 'M' correct...

  • file-k100.xml
  • file-k10.xml
  • file-k20.xml
  • file-M100.xml
  • file-M10.xml
  • file-M20.xml
  • file-10.xml
  • file-20.xml
  • file-100.xml

I can use ls -1 | sort -n -k 1.7 to get none of it correct

  • file-100.xml
  • file-10.xml
  • file-20.xml
  • file-k10.xml
  • file-M10.xml
  • file-k20.xml
  • file-M20.xml
  • file-k100.xml
  • file-M100.xml

Okay, fine. Let's really get it right. ls -1 | grep "file-[0-9]*\.xml" | sort -n -k1.6 && ls -1 file-k*.xml | sort -n -k1.7 && ls -1 file-M*.xml | sort -n -k1.7

  • file-10.xml
  • file-20.xml
  • file-100.xml
  • file-k10.xml
  • file-k20.xml
  • file-k100.xml
  • file-M10.xml
  • file-M20.xml
  • file-M100.xml

Whew! Boy glad the "power of the linux command line" saved me there. (This isn't practical for my situation, because instead of ls -1 I have a command that is another line or two long)

Now, the Windows behavior is simple, elegant, and does what you want it to do 99% of the time. Why can't I have that in linux? Why oh why does sort not have a "automagic sort numbers in a way that doesn't make me bang head into wall" switch?

Here's the pseudo-code for C++:

bool compare_two_strings_to_avoid_head_injury(string a, string b)
{
    string::iterator ai = a.begin();
    string::iterator bi = b.begin();
    for(; ai != a.end() && bi != b.end(); ai++, bi++)
    {
        if (*ai is numerical)
            gobble up the number incrementing ai past numerical chars;
        if (*bi is numerical)
            gobble up the number incrementing bi past numerical chars;
        actually compare *ai and *bi and/or the gobbled up number(s) here
            to determine if we need to compare more chars or can return the 
            answer now;
    }
    return something here;
}

Was that so hard? Can someone put this in sort and send me a copy? Please?

like image 542
Scott Avatar asked Jul 24 '10 02:07

Scott


People also ask

How do I sort numerically in Linux?

How to sort by number. To sort by number pass the -n option to sort . This will sort from lowest number to highest number and write the result to standard output. Suppose a file exists with a list of items of clothing that has a number at the start of the line and needs to be sorted numerically.

Which command is used to sort the numeric file?

The sort command sorts the contents of a file, in numeric or alphabetic order, and prints the results to standard output (usually the terminal screen). The original file is unaffected. The output of the sort command will then be stored in a file named newfilename in the current directory.

How do I sort a text file alphabetically in Linux?

In the Linux system, you will find one command named sort. This command can sort your data alphabetically. Here flag -k is used to select a field for sorting.

How do I reverse sort in Linux?

-r Option: Sorting In Reverse Order: You can perform a reverse-order sort using the -r flag. the -r flag is an option of the sort command which sorts the input file in reverse order i.e. descending order by default.


1 Answers

Try sort --version-sort -f

  • file-10.xml
  • file-20.xml
  • file-100.xml
  • file-k10.xml
  • file-k20.xml
  • file-k100.xml
  • file-M10.xml
  • file-M20.xml
  • file-M100.xml

The -f option is to ignore case (otherwise, it would put the k's and M's in the wrong order in this example). However, I don't think sort isn't properly interpreting the letters k and M as thousands and millions, if that was your goal - its just alphabetical order.

like image 105
Sam Bayless Avatar answered Sep 20 '22 11:09

Sam Bayless