[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: "sort" utility short comming or bug: cannot sort according to "human
From: |
Pádraig Brady |
Subject: |
Re: "sort" utility short comming or bug: cannot sort according to "human format" criterion. |
Date: |
Thu, 05 Jan 2006 11:06:02 +0000 |
User-agent: |
Mozilla Thunderbird 1.0.7 (X11/20051013) |
Pádraig Brady wrote:
>Andre Gompel wrote:
>
>
>
>>Dear colleague:
>> it looks like a bug... or at least a short comming.
>>
>>If I use the -n or -g option I cannot sort according to the output format of
>>the "du" or "ls" commands.
>>
>>Example:
>>
>> du -chs * |sort -n |more
>>
>>I am not sure what would be the best approach, but I would tend to add one
>>more option (says -h for "human format" compatibility).
>>
>>
>>
>>
>I see what you mean, but that would definitely not
>be a stable sort as info is lost in the number -> human conversion.
>You really need to sort before the human conversion.
>Have a look at: http://www.pixelbeat.org/scripts/dutop
>
>
Actually thinking a bit more about this, a seperate util for
formating numbers for human consumption would be useful.
I threw the attached python prog together as an example.
for the above example you would use it like:
du -cbs * | sort -k1,1n | ./human.py --columns=1 --divisor=1000
Do others think a util like this would a useful addition to coreutils?
cheers,
Pádraig.
#!/usr/bin/env python
#TODO: support ranges for --column option
#TODO: support converting from back from "human" numbers to "standard" numbers
#TODO: support aligning output like `column -t`
#TODO: support --col-delimiters option
import os
import sys
import getopt
def Usage():
print "Usage: %s [OPTION] [PATH]" % os.path.split(sys.argv[0])[1]
print " --divisor=value The default value is 1 which means insert
thousands seperator."
print " Other possible values are 1000 and 1024."
print " --columns=1,2,3"
print " --help display help"
try:
lOpts, lArgs = getopt.getopt(sys.argv[1:], "",
["help","divisor=","columns="])
if len(lArgs) == 0:
infile = sys.stdin
elif len(lArgs) == 1:
infile = file(lArgs[0])
else:
Usage()
sys.exit(None)
if ("--help","") in lOpts:
Usage()
sys.exit(None)
divisor=1
columns=[]
for opt in lOpts:
if opt[0] == "--divisor":
divisor=opt[1]
if divisor == "1":
divisor = 1
elif divisor=="1000" or divisor=="1024":
divisor = float(divisor)
else:
raise getopt.error, "Invalid divisor"
if opt[0] == "--columns":
columns=[int(col) for col in opt[1].split(",")]
except getopt.error, msg:
print msg
print
Usage()
sys.exit(2)
import locale
locale.setlocale(locale.LC_ALL,'')
def human(num, power=" "):
if divisor == 1:
return locale.format("%.1f",num,1)
powers=[" ","K","M","G","T"]
while num >= 1000:
num /= divisor
power=powers[powers.index(power)+1]
human(num,power)
return "%6.1f%s" % (num,power)
for line in infile:
line = line.split()
column=0
for str in line:
column+=1
if not len(columns) or column in columns:
try:
num = float(str)
str = human(num)
if str.endswith(".0 "):
str = str[:-3]+" "
elif str.endswith(".0"):
str = str[:-2]
except:
pass
print str,
print