• Posts
  • RSS
  • ◂◂RSS
  • Contact

  • Sorting mixed lists of numbers and strings

    June 26th, 2009
    programming  [html]
    Imagine you have this list:
    fname_0006.v0_word 2
    fname_0007.v0_word 12
    fname_0001.v0_word 15
    fname_0002.v0_word 23
    fname_0003.v0_word 5
    fname_0003.v0_word 7
    fname_0005.v0_word 8
    fname_0006.v0_word 9
    fname_0007.v0_word 11
    fname_0005.v0_word 24
    
    Imagine further that you want to sort it. Unfortunately, I can't get gnu sort to let me specify which fields are numeric and which now. That is, I can do:
    $ cat file.txt | sort
    fname_0001.v0_word 15
    fname_0002.v0_word 23
    fname_0003.v0_word 5
    fname_0003.v0_word 7
    fname_0005.v0_word 24
    fname_0005.v0_word 8
    fname_0006.v0_word 2
    fname_0006.v0_word 9
    fname_0007.v0_word 11
    fname_0007.v0_word 12
    
    Or I can do:
    $ cat file.txt | sort -n
    fname_0001.v0_word 15
    fname_0002.v0_word 23
    fname_0003.v0_word 5
    fname_0003.v0_word 7
    fname_0005.v0_word 24
    fname_0005.v0_word 8
    fname_0006.v0_word 2
    fname_0006.v0_word 9
    fname_0007.v0_word 11
    fname_0007.v0_word 12
    
    Or I can do:
    $ cat file.txt | sort -n -k1,1 -k2,2
    fname_0006.v0_word 2
    fname_0003.v0_word 5
    fname_0003.v0_word 7
    fname_0005.v0_word 8
    fname_0006.v0_word 9
    fname_0007.v0_word 11
    fname_0007.v0_word 12
    fname_0001.v0_word 15
    fname_0002.v0_word 23
    fname_0005.v0_word 24
    
    You might think this would work:
    $ cat file.txt | sort -k1,1 -kn2,2
    fname_0006.v0_word 2
    fname_0003.v0_word 5
    fname_0003.v0_word 7
    fname_0005.v0_word 8
    fname_0006.v0_word 9
    fname_0007.v0_word 11
    fname_0007.v0_word 12
    fname_0001.v0_word 15
    fname_0002.v0_word 23
    fname_0005.v0_word 24
    
    But nothing seems to make it do the right thing. So I abandoned sort for python:
    $ cat simple_sorter.py
    import fileinput
    
    def tidy(x):
        try:
            return int(x)
        except ValueError:
            return x
    
    line_bits = []
    
    for line in fileinput.input():
        line_bits.append([tidy(field) for field in line.split()])
    
    for bits in sorted(line_bits):
        print " ".join(str(bit) for bit in bits)
    
    $ cat tmp.txt | python simple_sorter.py
    fname_0001.v0_word 15
    fname_0002.v0_word 23
    fname_0003.v0_word 5
    fname_0003.v0_word 7
    fname_0005.v0_word 8
    fname_0005.v0_word 24
    fname_0006.v0_word 2
    fname_0006.v0_word 9
    fname_0007.v0_word 11
    fname_0007.v0_word 12
    

    Update 2013-08-22: Thinking now, if I had to do it on the terminal I would do:

    $ cat file | awk '{print $1, $2+1000}' | sort | awk '{print $1, $2-1000}'
    fname_0001.v0_word 15
    fname_0002.v0_word 23
    fname_0003.v0_word 5
    fname_0003.v0_word 7
    fname_0005.v0_word 8
    fname_0005.v0_word 24
    fname_0006.v0_word 2
    fname_0006.v0_word 9
    fname_0007.v0_word 11
    fname_0007.v0_word 12
    
    Adding 1000 (or any number with more digits than your biggest number) puts in leading digits, fixing sorting. It's basically decorate-sort-undecorate.

    Comment via: facebook

    Recent posts on blogs I like:

    What should we do about network-effect monopolies?

    Many large companies today are software monopolies that give their product away for free to get monopoly status, then do horrible things. Can we do anything about this?

    via benkuhn.net July 5, 2020

    More on the Deutschlandtakt

    The Deutschlandtakt plans are out now. They cover investment through 2040, but even beforehand, there’s a plan for something like a national integrated timetable by 2030, with trains connecting the major cities every 30 minutes rather than hourly. But the…

    via Pedestrian Observations July 1, 2020

    How do cars fare in crash tests they're not specifically optimized for?

    Any time you have a benchmark that gets taken seriously, some people will start gaming the benchmark. Some famous examples in computing are the CPU benchmark specfp and video game benchmarks. With specfp, Sun managed to increase its score on 179.art (a su…

    via Posts on Dan Luu June 30, 2020

    more     (via openring)


  • Posts
  • RSS
  • ◂◂RSS
  • Contact