How to sort with ls -lh command?

Hi All

I am trying to sort files from largest to smallest

using this command

ls -lh /home/sid | awk '$9 !~/unwantedfile/{print $5,$3,$6,$7,$8,$9}' |sort -n -r

I am using awk and printing in this format print $5,$3,$6,$7,$8,$9, so that sort would use the values in $5 and print in descending order. But I get random sorting

I am using solaris version
Please advise

Does the Solaris version support -S (sort by size): ls -Slh /home/sid

... | sort -nr -k1,1

ls: illegal option -- S
usage: ls -1RaAdCxmnlhogrtuvVcpFbqisfHLeE@ [files]

My solaris version

bash-3.2$ uname -a
SunOS 5.10 Generic_150400-02 sun4u sparc SUNW,Sun-Fire-15000

---------- Post updated at 05:00 PM ---------- Previous update was at 04:58 PM ----------

Threw this error

sort: can't stat k1,1: No such file or directory

what was your final execution line?

how about this this:

ls -lh /home/sid | awk '
$9 !~/unwantedfile/{
  bytes=$5 * 1024^index("KMGTPEZY", toupper(substr($5,length($5))));
  printf "%.0f ", bytes
  print $5,$3,$6,$7,$8,$9
} ' | sort -n -r | sed 's/[^ ]* //'
1 Like

For ascending order try:

ls -l | sort +4n  

For descending order try:

ls -l | sort +4nr 
1 Like

I think the point here is the OP the listing sorted with human-readable sizes.

My mistake, I missed that.

I am not in front of a solaris host at the moment but IIRC later versions of solaris du -h will display file sizes in human readable format - that will be easier to sort than ls -lh.

EDIT: Some examples:

du -k <directory>
du -m <directory>
du -g <directory>

and then sort the output.

That's not really sortable... K comes after G alphabetically and all.

Agreed, and posting #6 matches the desired input and output

1 Like

Thanks it almost works ,but when we have K and G And M
it doesn't sort numerically but alphabetically

---------- Post updated at 09:47 PM ---------- Previous update was at 09:45 PM ----------

You sir are a genius!! It worked perfectly !!!

If you don't ming could you explain this code. What is index and why that special word KMGTPEZY and the last sed part

Index is a built-in function in awk that finds the position of a string within another.

For example index("the quick brown fox", "r") would return 12 as the first "r" found in the string is 12 characters from the front on the string.

the string KMGTPEZY represents the suffixes (Kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta). So index gives us 1 for K, 2 for M, 3 for G, etc. We can then raise 1024 to this number to get the conversion factor for the suffix.

In addition to what Chubler_XL has already said, the entire purpose of the code:

bytes=$5 * 1024^index("KMGTPEZY", toupper(substr($5,length($5))));
  printf "%.0f ", bytes

is to undo what the ls -h option did and give you an approximation to the actual file size in bytes that can be sorted numerically. If you were willing to change the 1st command in your pipeline from ls -lh to just ls -l , those two statements could be removed from the awk script and the sed command (which deletes the file size in bytes from the output) could be removed from the end of the pipeline.

With Perl:

ls -lh | perl -e'
@l{ K, M, G, T, P, E, Z, Y } = ( 1 .. 8 );
print sort {
    ($aa) = $a =~ /(\w)\s+/;
    ($bb) = $b =~ /(\w)\s+/;
    $l{$aa} <=> $l{$bb} || $a <=> $b
  }<>'