How to sort human readable sizeA standard tool to convert a byte-count into human KiB MiB etc; like du, ls1Human-readable ls output under AIX?How to display “human-readable” file sizes in find results?Find, count and sort all audio files. ALAC (M4A) filesSort command inconsistent behaviorSort output of awk except for first line?Find human-readable filesSort function doesn't workFind and sort by file sizeHow do I get rid of human readable format for ls?
how can I enforce the prohibition on love potions?
Is this bible in Koine Greek?
B1/B2 visa lost along with my passport
Is there evidence for Col. Vindman literally being a "Never Trump"?
Fast symmetric key cryptography class
Is it possible to be admitted to CS PhD programs (in US) with scholarship at age 18?
Wood versus marble rolling pin 'performance'
During a log backup is the data backed up to the start or end of the operation?
How should chips with pins on bottom be drawn?
In what way were Renaissance battles like chess matches?
How should I conceal gaps between laminate flooring and wall trim?
How exactly do you avoid fooling yourself?
Why does telnet on a non existent port not directly reject, but time out?
Is there a simple way to typeset playing cards?
Adding coordinate constant to file in QGIS
Instant coffee melts like chocolate
Remove folder if it has another folder with the same started numbers
Was Tim's reaction to the electric fence realistic?
Were mixed race kids theorized to look like zebras?
Graph with cropped letters
If I am just replacing the car engine, do I need to replace the odometer as well?
What is the type of English used in the King James Bible Called?
Teleportation is invented but it has nasty side-effects % of the time, how will that affect usage of the technology?
How does an all-female medieval country maintain itself?
How to sort human readable size
A standard tool to convert a byte-count into human KiB MiB etc; like du, ls1Human-readable ls output under AIX?How to display “human-readable” file sizes in find results?Find, count and sort all audio files. ALAC (M4A) filesSort command inconsistent behaviorSort output of awk except for first line?Find human-readable filesSort function doesn't workFind and sort by file sizeHow do I get rid of human readable format for ls?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;
I'm basically looking for files then sorting by the size. The script works if I don't sort the size by human readable. But I want the size to be human readable. How can I sort sizes that are human readable?
For example:
ls -l | sort -k 5 -n | awk 'print $9 " " $5'
This works as expected, I got the size of my files in bytes ascending:
1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850
Now, I want the size to be human readable, so I added an -h parameter to ls, and now some files are out of order:
ls -lh | sort -k 5 -n | awk 'print $9 " " $5'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K
find ls sort
|
show 2 more comments
I'm basically looking for files then sorting by the size. The script works if I don't sort the size by human readable. But I want the size to be human readable. How can I sort sizes that are human readable?
For example:
ls -l | sort -k 5 -n | awk 'print $9 " " $5'
This works as expected, I got the size of my files in bytes ascending:
1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850
Now, I want the size to be human readable, so I added an -h parameter to ls, and now some files are out of order:
ls -lh | sort -k 5 -n | awk 'print $9 " " $5'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K
find ls sort
-k 5
— how does that work?
– ctrl-alt-delor
Jun 13 at 19:27
@ctrl-alt-delor: I believe the size is in the 5th column of thels
output
– Jesse_b
Jun 13 at 19:30
2
Usingdu
instead ofls
could be a good idea.
– xenoid
Jun 13 at 19:34
... orfind
’s-printf
with its%p
and%s
formatters (followed by a “humanisation” of the sizes).
– Stephen Kitt
Jun 13 at 19:35
@Jesse_b my error, I just assumed that the data in the question (marked as this is what I got) was the sorted input.I was wrong.
– ctrl-alt-delor
Jun 13 at 22:10
|
show 2 more comments
I'm basically looking for files then sorting by the size. The script works if I don't sort the size by human readable. But I want the size to be human readable. How can I sort sizes that are human readable?
For example:
ls -l | sort -k 5 -n | awk 'print $9 " " $5'
This works as expected, I got the size of my files in bytes ascending:
1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850
Now, I want the size to be human readable, so I added an -h parameter to ls, and now some files are out of order:
ls -lh | sort -k 5 -n | awk 'print $9 " " $5'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K
find ls sort
I'm basically looking for files then sorting by the size. The script works if I don't sort the size by human readable. But I want the size to be human readable. How can I sort sizes that are human readable?
For example:
ls -l | sort -k 5 -n | awk 'print $9 " " $5'
This works as expected, I got the size of my files in bytes ascending:
1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850
Now, I want the size to be human readable, so I added an -h parameter to ls, and now some files are out of order:
ls -lh | sort -k 5 -n | awk 'print $9 " " $5'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K
find ls sort
find ls sort
edited Jun 14 at 2:23
tvo000
asked Jun 13 at 19:13
tvo000tvo000
587 bronze badges
587 bronze badges
-k 5
— how does that work?
– ctrl-alt-delor
Jun 13 at 19:27
@ctrl-alt-delor: I believe the size is in the 5th column of thels
output
– Jesse_b
Jun 13 at 19:30
2
Usingdu
instead ofls
could be a good idea.
– xenoid
Jun 13 at 19:34
... orfind
’s-printf
with its%p
and%s
formatters (followed by a “humanisation” of the sizes).
– Stephen Kitt
Jun 13 at 19:35
@Jesse_b my error, I just assumed that the data in the question (marked as this is what I got) was the sorted input.I was wrong.
– ctrl-alt-delor
Jun 13 at 22:10
|
show 2 more comments
-k 5
— how does that work?
– ctrl-alt-delor
Jun 13 at 19:27
@ctrl-alt-delor: I believe the size is in the 5th column of thels
output
– Jesse_b
Jun 13 at 19:30
2
Usingdu
instead ofls
could be a good idea.
– xenoid
Jun 13 at 19:34
... orfind
’s-printf
with its%p
and%s
formatters (followed by a “humanisation” of the sizes).
– Stephen Kitt
Jun 13 at 19:35
@Jesse_b my error, I just assumed that the data in the question (marked as this is what I got) was the sorted input.I was wrong.
– ctrl-alt-delor
Jun 13 at 22:10
-k 5
— how does that work?– ctrl-alt-delor
Jun 13 at 19:27
-k 5
— how does that work?– ctrl-alt-delor
Jun 13 at 19:27
@ctrl-alt-delor: I believe the size is in the 5th column of the
ls
output– Jesse_b
Jun 13 at 19:30
@ctrl-alt-delor: I believe the size is in the 5th column of the
ls
output– Jesse_b
Jun 13 at 19:30
2
2
Using
du
instead of ls
could be a good idea.– xenoid
Jun 13 at 19:34
Using
du
instead of ls
could be a good idea.– xenoid
Jun 13 at 19:34
... or
find
’s -printf
with its %p
and %s
formatters (followed by a “humanisation” of the sizes).– Stephen Kitt
Jun 13 at 19:35
... or
find
’s -printf
with its %p
and %s
formatters (followed by a “humanisation” of the sizes).– Stephen Kitt
Jun 13 at 19:35
@Jesse_b my error, I just assumed that the data in the question (marked as this is what I got) was the sorted input.I was wrong.
– ctrl-alt-delor
Jun 13 at 22:10
@Jesse_b my error, I just assumed that the data in the question (marked as this is what I got) was the sorted input.I was wrong.
– ctrl-alt-delor
Jun 13 at 22:10
|
show 2 more comments
5 Answers
5
active
oldest
votes
Try sort -h k2
-h, --human-numeric-sort
compare human readable numbers (e.g., 2K 1G)
It is part of gnu sort, BSD sort, and others.
5
Shouldn't parsing the output ofls
be avoided?
– Tomasz
Jun 13 at 19:26
3
@Tomasz Not always. If it provides the output you need, piping it to another formatting operation is not particularly dangerous. What you should not do is loop over the output ofls
, and instead use file globbing directly. Globbing alone won't work here. That said, I would probably preferdu
for this.
– Bloodgain
Jun 14 at 22:33
1
@Bloodgain the ls format is not guaranteed to be the same across systems/ls binaries, so parsing it portably is considered impossible.
– D. Ben Knoble
Jun 17 at 3:00
1
Also, filenames with whitespace will mangle things
– D. Ben Knoble
Jun 17 at 3:06
1
@Bloodgain :files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo $#files[@]
(I might have the is a symlink test switch wrong). If you don’t care about symlinks,files=(*); echo $#files[@]
, which becomes portable if you useset
and not arrays.
– D. Ben Knoble
Jun 21 at 14:15
|
show 3 more comments
ls
has this functionality built in, use the -S
option and sort in reverse order: ls -lShr
-r, --reverse
reverse order while sorting
-S sort by file size, largest first
1
-h
is not a standardls
option, but must be usable if OP already has it. The rest are standard, and it's certainly the answer I would have written.
– Toby Speight
Jun 14 at 10:44
5
+1 Don't mess around parsing the output ofls
.
– David Richerby
Jun 14 at 10:59
This is the best answer, but it should include the info in @Toby's comment:-S
might not be available for yourls
. FWIW,-S
is supported even with Emacs's libraryls-lisp.el
, which is used when the OS has nols
. It works in Emacs on MS Windows, for example.
– Drew
Jun 14 at 16:37
This should be the accepted answer.
– scatter
Jun 14 at 17:32
1
@Drew: Toby's comment says that-h
may not be universally available, but OP is already using it anyway.-S
really should be universally available, because it's in the POSIX link that Toby provides. However, quite a few non-POSIX toolkits do exist out there.
– Kevin
Jun 16 at 18:58
|
show 8 more comments
Since no specific shell was mentioned, here's how to do the whole thing in the zsh
shell:
ls -lhf **/*(.Lk-1024oL)
The **
glob pattern matches like *
but across /
in pathnames, i.e. like a recursive search would do.
The ls
command would enable human readable sizes with -h
, and long list output format with -l
. The -f
option disables sorting, so ls
would just list the files in the order they are given.
This order is arranged by the **/*(.Lk-1024oL)
filename globbing pattern so that the smaller files are listed first. The **/*
bit matches every file and directory in this directory and below, but the (...)
modifies the glob's behaviour (it's a "glob qualifier").
It's the oL
at the end that orders (o
) the names by file size (L
, "length").
The .
at the start makes the glob only match regular files (no directories).
The Lk-1024
bit selects files whose size is less than 1024 KB ("length in KB less than 1024").
If zsh
is not your primary interactive shell, then you could use
zsh -c 'ls -lf **/*(.Lk-1024oL)'
Use setopt GLOB_DOTS
(or zsh -o GLOB_DOTS -c ...
)
to also match hidden names. ... or just add D
to the glob qualifier string.
Expanding on the above, assuming that you'd want a 2-column output with pathnames and human readable sizes, and also assuming that you have numfmt
from GNU coreutils,
zmodload -F zsh/stat b:zstat
for pathname in **/*(.Lk-1024oL); do
printf '%st%sn' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done
or, quicker,
paste <( printf '%sn' **/*(.Lk-1024oL) )
<( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )
add a comment
|
If your sort
does not have the -h
option you could use an (albeit very long) awk command like the following:
find . -type f -size -1024k -exec ls -al ; | sort -k 5 -n | awk 'if ($5 > 1099511627776) print $9,$5/1024/1024/1024/1024"T" else if ($5 > 1073741824) print $9,$5/1024/1024/1024"G" else if ($5 > 1048576) print $9,$5/1024/1024"M" else if ($5 > 1024) print $9,$5/1024"K" else print $9,$5"B"' | column -t
This will sort your output in bytes and then convert them to their human readable size afterward.
add a comment
|
Would this work?
ls -l | awk 'if ($5<=1024) print' | sort -k 5 -n | awk 'print $9"t"substr($5/1024,1,3)"k" '| column -t
The first awk
exp will look for the files lesser than 1M and the second one will take the byte size from the result and convert it to the KB and prints the first 3 elements to give a human-readable size.
That does not really solve OPs question - it only looks in the current directory and will only print regular files. Also will compare against 1Kb instead of 1MB. Finally we are after answers with some explanation about why the code works.
– grochmal
Jun 13 at 21:53
My bad added what it does.
– Vignesh SP
Jun 13 at 22:16
add a comment
|
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f524760%2fhow-to-sort-human-readable-size%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
Try sort -h k2
-h, --human-numeric-sort
compare human readable numbers (e.g., 2K 1G)
It is part of gnu sort, BSD sort, and others.
5
Shouldn't parsing the output ofls
be avoided?
– Tomasz
Jun 13 at 19:26
3
@Tomasz Not always. If it provides the output you need, piping it to another formatting operation is not particularly dangerous. What you should not do is loop over the output ofls
, and instead use file globbing directly. Globbing alone won't work here. That said, I would probably preferdu
for this.
– Bloodgain
Jun 14 at 22:33
1
@Bloodgain the ls format is not guaranteed to be the same across systems/ls binaries, so parsing it portably is considered impossible.
– D. Ben Knoble
Jun 17 at 3:00
1
Also, filenames with whitespace will mangle things
– D. Ben Knoble
Jun 17 at 3:06
1
@Bloodgain :files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo $#files[@]
(I might have the is a symlink test switch wrong). If you don’t care about symlinks,files=(*); echo $#files[@]
, which becomes portable if you useset
and not arrays.
– D. Ben Knoble
Jun 21 at 14:15
|
show 3 more comments
Try sort -h k2
-h, --human-numeric-sort
compare human readable numbers (e.g., 2K 1G)
It is part of gnu sort, BSD sort, and others.
5
Shouldn't parsing the output ofls
be avoided?
– Tomasz
Jun 13 at 19:26
3
@Tomasz Not always. If it provides the output you need, piping it to another formatting operation is not particularly dangerous. What you should not do is loop over the output ofls
, and instead use file globbing directly. Globbing alone won't work here. That said, I would probably preferdu
for this.
– Bloodgain
Jun 14 at 22:33
1
@Bloodgain the ls format is not guaranteed to be the same across systems/ls binaries, so parsing it portably is considered impossible.
– D. Ben Knoble
Jun 17 at 3:00
1
Also, filenames with whitespace will mangle things
– D. Ben Knoble
Jun 17 at 3:06
1
@Bloodgain :files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo $#files[@]
(I might have the is a symlink test switch wrong). If you don’t care about symlinks,files=(*); echo $#files[@]
, which becomes portable if you useset
and not arrays.
– D. Ben Knoble
Jun 21 at 14:15
|
show 3 more comments
Try sort -h k2
-h, --human-numeric-sort
compare human readable numbers (e.g., 2K 1G)
It is part of gnu sort, BSD sort, and others.
Try sort -h k2
-h, --human-numeric-sort
compare human readable numbers (e.g., 2K 1G)
It is part of gnu sort, BSD sort, and others.
edited Jun 13 at 19:24
answered Jun 13 at 19:23
ctrl-alt-delorctrl-alt-delor
14.8k6 gold badges34 silver badges65 bronze badges
14.8k6 gold badges34 silver badges65 bronze badges
5
Shouldn't parsing the output ofls
be avoided?
– Tomasz
Jun 13 at 19:26
3
@Tomasz Not always. If it provides the output you need, piping it to another formatting operation is not particularly dangerous. What you should not do is loop over the output ofls
, and instead use file globbing directly. Globbing alone won't work here. That said, I would probably preferdu
for this.
– Bloodgain
Jun 14 at 22:33
1
@Bloodgain the ls format is not guaranteed to be the same across systems/ls binaries, so parsing it portably is considered impossible.
– D. Ben Knoble
Jun 17 at 3:00
1
Also, filenames with whitespace will mangle things
– D. Ben Knoble
Jun 17 at 3:06
1
@Bloodgain :files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo $#files[@]
(I might have the is a symlink test switch wrong). If you don’t care about symlinks,files=(*); echo $#files[@]
, which becomes portable if you useset
and not arrays.
– D. Ben Knoble
Jun 21 at 14:15
|
show 3 more comments
5
Shouldn't parsing the output ofls
be avoided?
– Tomasz
Jun 13 at 19:26
3
@Tomasz Not always. If it provides the output you need, piping it to another formatting operation is not particularly dangerous. What you should not do is loop over the output ofls
, and instead use file globbing directly. Globbing alone won't work here. That said, I would probably preferdu
for this.
– Bloodgain
Jun 14 at 22:33
1
@Bloodgain the ls format is not guaranteed to be the same across systems/ls binaries, so parsing it portably is considered impossible.
– D. Ben Knoble
Jun 17 at 3:00
1
Also, filenames with whitespace will mangle things
– D. Ben Knoble
Jun 17 at 3:06
1
@Bloodgain :files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo $#files[@]
(I might have the is a symlink test switch wrong). If you don’t care about symlinks,files=(*); echo $#files[@]
, which becomes portable if you useset
and not arrays.
– D. Ben Knoble
Jun 21 at 14:15
5
5
Shouldn't parsing the output of
ls
be avoided?– Tomasz
Jun 13 at 19:26
Shouldn't parsing the output of
ls
be avoided?– Tomasz
Jun 13 at 19:26
3
3
@Tomasz Not always. If it provides the output you need, piping it to another formatting operation is not particularly dangerous. What you should not do is loop over the output of
ls
, and instead use file globbing directly. Globbing alone won't work here. That said, I would probably prefer du
for this.– Bloodgain
Jun 14 at 22:33
@Tomasz Not always. If it provides the output you need, piping it to another formatting operation is not particularly dangerous. What you should not do is loop over the output of
ls
, and instead use file globbing directly. Globbing alone won't work here. That said, I would probably prefer du
for this.– Bloodgain
Jun 14 at 22:33
1
1
@Bloodgain the ls format is not guaranteed to be the same across systems/ls binaries, so parsing it portably is considered impossible.
– D. Ben Knoble
Jun 17 at 3:00
@Bloodgain the ls format is not guaranteed to be the same across systems/ls binaries, so parsing it portably is considered impossible.
– D. Ben Knoble
Jun 17 at 3:00
1
1
Also, filenames with whitespace will mangle things
– D. Ben Knoble
Jun 17 at 3:06
Also, filenames with whitespace will mangle things
– D. Ben Knoble
Jun 17 at 3:06
1
1
@Bloodgain :
files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo $#files[@]
(I might have the is a symlink test switch wrong). If you don’t care about symlinks, files=(*); echo $#files[@]
, which becomes portable if you use set
and not arrays.– D. Ben Knoble
Jun 21 at 14:15
@Bloodgain :
files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo $#files[@]
(I might have the is a symlink test switch wrong). If you don’t care about symlinks, files=(*); echo $#files[@]
, which becomes portable if you use set
and not arrays.– D. Ben Knoble
Jun 21 at 14:15
|
show 3 more comments
ls
has this functionality built in, use the -S
option and sort in reverse order: ls -lShr
-r, --reverse
reverse order while sorting
-S sort by file size, largest first
1
-h
is not a standardls
option, but must be usable if OP already has it. The rest are standard, and it's certainly the answer I would have written.
– Toby Speight
Jun 14 at 10:44
5
+1 Don't mess around parsing the output ofls
.
– David Richerby
Jun 14 at 10:59
This is the best answer, but it should include the info in @Toby's comment:-S
might not be available for yourls
. FWIW,-S
is supported even with Emacs's libraryls-lisp.el
, which is used when the OS has nols
. It works in Emacs on MS Windows, for example.
– Drew
Jun 14 at 16:37
This should be the accepted answer.
– scatter
Jun 14 at 17:32
1
@Drew: Toby's comment says that-h
may not be universally available, but OP is already using it anyway.-S
really should be universally available, because it's in the POSIX link that Toby provides. However, quite a few non-POSIX toolkits do exist out there.
– Kevin
Jun 16 at 18:58
|
show 8 more comments
ls
has this functionality built in, use the -S
option and sort in reverse order: ls -lShr
-r, --reverse
reverse order while sorting
-S sort by file size, largest first
1
-h
is not a standardls
option, but must be usable if OP already has it. The rest are standard, and it's certainly the answer I would have written.
– Toby Speight
Jun 14 at 10:44
5
+1 Don't mess around parsing the output ofls
.
– David Richerby
Jun 14 at 10:59
This is the best answer, but it should include the info in @Toby's comment:-S
might not be available for yourls
. FWIW,-S
is supported even with Emacs's libraryls-lisp.el
, which is used when the OS has nols
. It works in Emacs on MS Windows, for example.
– Drew
Jun 14 at 16:37
This should be the accepted answer.
– scatter
Jun 14 at 17:32
1
@Drew: Toby's comment says that-h
may not be universally available, but OP is already using it anyway.-S
really should be universally available, because it's in the POSIX link that Toby provides. However, quite a few non-POSIX toolkits do exist out there.
– Kevin
Jun 16 at 18:58
|
show 8 more comments
ls
has this functionality built in, use the -S
option and sort in reverse order: ls -lShr
-r, --reverse
reverse order while sorting
-S sort by file size, largest first
ls
has this functionality built in, use the -S
option and sort in reverse order: ls -lShr
-r, --reverse
reverse order while sorting
-S sort by file size, largest first
answered Jun 14 at 3:46
Mark McKinstryMark McKinstry
10.1k3 gold badges25 silver badges24 bronze badges
10.1k3 gold badges25 silver badges24 bronze badges
1
-h
is not a standardls
option, but must be usable if OP already has it. The rest are standard, and it's certainly the answer I would have written.
– Toby Speight
Jun 14 at 10:44
5
+1 Don't mess around parsing the output ofls
.
– David Richerby
Jun 14 at 10:59
This is the best answer, but it should include the info in @Toby's comment:-S
might not be available for yourls
. FWIW,-S
is supported even with Emacs's libraryls-lisp.el
, which is used when the OS has nols
. It works in Emacs on MS Windows, for example.
– Drew
Jun 14 at 16:37
This should be the accepted answer.
– scatter
Jun 14 at 17:32
1
@Drew: Toby's comment says that-h
may not be universally available, but OP is already using it anyway.-S
really should be universally available, because it's in the POSIX link that Toby provides. However, quite a few non-POSIX toolkits do exist out there.
– Kevin
Jun 16 at 18:58
|
show 8 more comments
1
-h
is not a standardls
option, but must be usable if OP already has it. The rest are standard, and it's certainly the answer I would have written.
– Toby Speight
Jun 14 at 10:44
5
+1 Don't mess around parsing the output ofls
.
– David Richerby
Jun 14 at 10:59
This is the best answer, but it should include the info in @Toby's comment:-S
might not be available for yourls
. FWIW,-S
is supported even with Emacs's libraryls-lisp.el
, which is used when the OS has nols
. It works in Emacs on MS Windows, for example.
– Drew
Jun 14 at 16:37
This should be the accepted answer.
– scatter
Jun 14 at 17:32
1
@Drew: Toby's comment says that-h
may not be universally available, but OP is already using it anyway.-S
really should be universally available, because it's in the POSIX link that Toby provides. However, quite a few non-POSIX toolkits do exist out there.
– Kevin
Jun 16 at 18:58
1
1
-h
is not a standard ls
option, but must be usable if OP already has it. The rest are standard, and it's certainly the answer I would have written.– Toby Speight
Jun 14 at 10:44
-h
is not a standard ls
option, but must be usable if OP already has it. The rest are standard, and it's certainly the answer I would have written.– Toby Speight
Jun 14 at 10:44
5
5
+1 Don't mess around parsing the output of
ls
.– David Richerby
Jun 14 at 10:59
+1 Don't mess around parsing the output of
ls
.– David Richerby
Jun 14 at 10:59
This is the best answer, but it should include the info in @Toby's comment:
-S
might not be available for your ls
. FWIW, -S
is supported even with Emacs's libraryls-lisp.el
, which is used when the OS has no ls
. It works in Emacs on MS Windows, for example.– Drew
Jun 14 at 16:37
This is the best answer, but it should include the info in @Toby's comment:
-S
might not be available for your ls
. FWIW, -S
is supported even with Emacs's libraryls-lisp.el
, which is used when the OS has no ls
. It works in Emacs on MS Windows, for example.– Drew
Jun 14 at 16:37
This should be the accepted answer.
– scatter
Jun 14 at 17:32
This should be the accepted answer.
– scatter
Jun 14 at 17:32
1
1
@Drew: Toby's comment says that
-h
may not be universally available, but OP is already using it anyway. -S
really should be universally available, because it's in the POSIX link that Toby provides. However, quite a few non-POSIX toolkits do exist out there.– Kevin
Jun 16 at 18:58
@Drew: Toby's comment says that
-h
may not be universally available, but OP is already using it anyway. -S
really should be universally available, because it's in the POSIX link that Toby provides. However, quite a few non-POSIX toolkits do exist out there.– Kevin
Jun 16 at 18:58
|
show 8 more comments
Since no specific shell was mentioned, here's how to do the whole thing in the zsh
shell:
ls -lhf **/*(.Lk-1024oL)
The **
glob pattern matches like *
but across /
in pathnames, i.e. like a recursive search would do.
The ls
command would enable human readable sizes with -h
, and long list output format with -l
. The -f
option disables sorting, so ls
would just list the files in the order they are given.
This order is arranged by the **/*(.Lk-1024oL)
filename globbing pattern so that the smaller files are listed first. The **/*
bit matches every file and directory in this directory and below, but the (...)
modifies the glob's behaviour (it's a "glob qualifier").
It's the oL
at the end that orders (o
) the names by file size (L
, "length").
The .
at the start makes the glob only match regular files (no directories).
The Lk-1024
bit selects files whose size is less than 1024 KB ("length in KB less than 1024").
If zsh
is not your primary interactive shell, then you could use
zsh -c 'ls -lf **/*(.Lk-1024oL)'
Use setopt GLOB_DOTS
(or zsh -o GLOB_DOTS -c ...
)
to also match hidden names. ... or just add D
to the glob qualifier string.
Expanding on the above, assuming that you'd want a 2-column output with pathnames and human readable sizes, and also assuming that you have numfmt
from GNU coreutils,
zmodload -F zsh/stat b:zstat
for pathname in **/*(.Lk-1024oL); do
printf '%st%sn' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done
or, quicker,
paste <( printf '%sn' **/*(.Lk-1024oL) )
<( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )
add a comment
|
Since no specific shell was mentioned, here's how to do the whole thing in the zsh
shell:
ls -lhf **/*(.Lk-1024oL)
The **
glob pattern matches like *
but across /
in pathnames, i.e. like a recursive search would do.
The ls
command would enable human readable sizes with -h
, and long list output format with -l
. The -f
option disables sorting, so ls
would just list the files in the order they are given.
This order is arranged by the **/*(.Lk-1024oL)
filename globbing pattern so that the smaller files are listed first. The **/*
bit matches every file and directory in this directory and below, but the (...)
modifies the glob's behaviour (it's a "glob qualifier").
It's the oL
at the end that orders (o
) the names by file size (L
, "length").
The .
at the start makes the glob only match regular files (no directories).
The Lk-1024
bit selects files whose size is less than 1024 KB ("length in KB less than 1024").
If zsh
is not your primary interactive shell, then you could use
zsh -c 'ls -lf **/*(.Lk-1024oL)'
Use setopt GLOB_DOTS
(or zsh -o GLOB_DOTS -c ...
)
to also match hidden names. ... or just add D
to the glob qualifier string.
Expanding on the above, assuming that you'd want a 2-column output with pathnames and human readable sizes, and also assuming that you have numfmt
from GNU coreutils,
zmodload -F zsh/stat b:zstat
for pathname in **/*(.Lk-1024oL); do
printf '%st%sn' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done
or, quicker,
paste <( printf '%sn' **/*(.Lk-1024oL) )
<( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )
add a comment
|
Since no specific shell was mentioned, here's how to do the whole thing in the zsh
shell:
ls -lhf **/*(.Lk-1024oL)
The **
glob pattern matches like *
but across /
in pathnames, i.e. like a recursive search would do.
The ls
command would enable human readable sizes with -h
, and long list output format with -l
. The -f
option disables sorting, so ls
would just list the files in the order they are given.
This order is arranged by the **/*(.Lk-1024oL)
filename globbing pattern so that the smaller files are listed first. The **/*
bit matches every file and directory in this directory and below, but the (...)
modifies the glob's behaviour (it's a "glob qualifier").
It's the oL
at the end that orders (o
) the names by file size (L
, "length").
The .
at the start makes the glob only match regular files (no directories).
The Lk-1024
bit selects files whose size is less than 1024 KB ("length in KB less than 1024").
If zsh
is not your primary interactive shell, then you could use
zsh -c 'ls -lf **/*(.Lk-1024oL)'
Use setopt GLOB_DOTS
(or zsh -o GLOB_DOTS -c ...
)
to also match hidden names. ... or just add D
to the glob qualifier string.
Expanding on the above, assuming that you'd want a 2-column output with pathnames and human readable sizes, and also assuming that you have numfmt
from GNU coreutils,
zmodload -F zsh/stat b:zstat
for pathname in **/*(.Lk-1024oL); do
printf '%st%sn' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done
or, quicker,
paste <( printf '%sn' **/*(.Lk-1024oL) )
<( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )
Since no specific shell was mentioned, here's how to do the whole thing in the zsh
shell:
ls -lhf **/*(.Lk-1024oL)
The **
glob pattern matches like *
but across /
in pathnames, i.e. like a recursive search would do.
The ls
command would enable human readable sizes with -h
, and long list output format with -l
. The -f
option disables sorting, so ls
would just list the files in the order they are given.
This order is arranged by the **/*(.Lk-1024oL)
filename globbing pattern so that the smaller files are listed first. The **/*
bit matches every file and directory in this directory and below, but the (...)
modifies the glob's behaviour (it's a "glob qualifier").
It's the oL
at the end that orders (o
) the names by file size (L
, "length").
The .
at the start makes the glob only match regular files (no directories).
The Lk-1024
bit selects files whose size is less than 1024 KB ("length in KB less than 1024").
If zsh
is not your primary interactive shell, then you could use
zsh -c 'ls -lf **/*(.Lk-1024oL)'
Use setopt GLOB_DOTS
(or zsh -o GLOB_DOTS -c ...
)
to also match hidden names. ... or just add D
to the glob qualifier string.
Expanding on the above, assuming that you'd want a 2-column output with pathnames and human readable sizes, and also assuming that you have numfmt
from GNU coreutils,
zmodload -F zsh/stat b:zstat
for pathname in **/*(.Lk-1024oL); do
printf '%st%sn' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done
or, quicker,
paste <( printf '%sn' **/*(.Lk-1024oL) )
<( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )
edited Jun 14 at 6:41
answered Jun 13 at 20:44
Kusalananda♦Kusalananda
170k20 gold badges328 silver badges531 bronze badges
170k20 gold badges328 silver badges531 bronze badges
add a comment
|
add a comment
|
If your sort
does not have the -h
option you could use an (albeit very long) awk command like the following:
find . -type f -size -1024k -exec ls -al ; | sort -k 5 -n | awk 'if ($5 > 1099511627776) print $9,$5/1024/1024/1024/1024"T" else if ($5 > 1073741824) print $9,$5/1024/1024/1024"G" else if ($5 > 1048576) print $9,$5/1024/1024"M" else if ($5 > 1024) print $9,$5/1024"K" else print $9,$5"B"' | column -t
This will sort your output in bytes and then convert them to their human readable size afterward.
add a comment
|
If your sort
does not have the -h
option you could use an (albeit very long) awk command like the following:
find . -type f -size -1024k -exec ls -al ; | sort -k 5 -n | awk 'if ($5 > 1099511627776) print $9,$5/1024/1024/1024/1024"T" else if ($5 > 1073741824) print $9,$5/1024/1024/1024"G" else if ($5 > 1048576) print $9,$5/1024/1024"M" else if ($5 > 1024) print $9,$5/1024"K" else print $9,$5"B"' | column -t
This will sort your output in bytes and then convert them to their human readable size afterward.
add a comment
|
If your sort
does not have the -h
option you could use an (albeit very long) awk command like the following:
find . -type f -size -1024k -exec ls -al ; | sort -k 5 -n | awk 'if ($5 > 1099511627776) print $9,$5/1024/1024/1024/1024"T" else if ($5 > 1073741824) print $9,$5/1024/1024/1024"G" else if ($5 > 1048576) print $9,$5/1024/1024"M" else if ($5 > 1024) print $9,$5/1024"K" else print $9,$5"B"' | column -t
This will sort your output in bytes and then convert them to their human readable size afterward.
If your sort
does not have the -h
option you could use an (albeit very long) awk command like the following:
find . -type f -size -1024k -exec ls -al ; | sort -k 5 -n | awk 'if ($5 > 1099511627776) print $9,$5/1024/1024/1024/1024"T" else if ($5 > 1073741824) print $9,$5/1024/1024/1024"G" else if ($5 > 1048576) print $9,$5/1024/1024"M" else if ($5 > 1024) print $9,$5/1024"K" else print $9,$5"B"' | column -t
This will sort your output in bytes and then convert them to their human readable size afterward.
edited Jun 13 at 22:18
answered Jun 13 at 19:32
Jesse_bJesse_b
19.9k3 gold badges47 silver badges90 bronze badges
19.9k3 gold badges47 silver badges90 bronze badges
add a comment
|
add a comment
|
Would this work?
ls -l | awk 'if ($5<=1024) print' | sort -k 5 -n | awk 'print $9"t"substr($5/1024,1,3)"k" '| column -t
The first awk
exp will look for the files lesser than 1M and the second one will take the byte size from the result and convert it to the KB and prints the first 3 elements to give a human-readable size.
That does not really solve OPs question - it only looks in the current directory and will only print regular files. Also will compare against 1Kb instead of 1MB. Finally we are after answers with some explanation about why the code works.
– grochmal
Jun 13 at 21:53
My bad added what it does.
– Vignesh SP
Jun 13 at 22:16
add a comment
|
Would this work?
ls -l | awk 'if ($5<=1024) print' | sort -k 5 -n | awk 'print $9"t"substr($5/1024,1,3)"k" '| column -t
The first awk
exp will look for the files lesser than 1M and the second one will take the byte size from the result and convert it to the KB and prints the first 3 elements to give a human-readable size.
That does not really solve OPs question - it only looks in the current directory and will only print regular files. Also will compare against 1Kb instead of 1MB. Finally we are after answers with some explanation about why the code works.
– grochmal
Jun 13 at 21:53
My bad added what it does.
– Vignesh SP
Jun 13 at 22:16
add a comment
|
Would this work?
ls -l | awk 'if ($5<=1024) print' | sort -k 5 -n | awk 'print $9"t"substr($5/1024,1,3)"k" '| column -t
The first awk
exp will look for the files lesser than 1M and the second one will take the byte size from the result and convert it to the KB and prints the first 3 elements to give a human-readable size.
Would this work?
ls -l | awk 'if ($5<=1024) print' | sort -k 5 -n | awk 'print $9"t"substr($5/1024,1,3)"k" '| column -t
The first awk
exp will look for the files lesser than 1M and the second one will take the byte size from the result and convert it to the KB and prints the first 3 elements to give a human-readable size.
edited Jun 13 at 22:15
answered Jun 13 at 20:29
Vignesh SPVignesh SP
2021 silver badge8 bronze badges
2021 silver badge8 bronze badges
That does not really solve OPs question - it only looks in the current directory and will only print regular files. Also will compare against 1Kb instead of 1MB. Finally we are after answers with some explanation about why the code works.
– grochmal
Jun 13 at 21:53
My bad added what it does.
– Vignesh SP
Jun 13 at 22:16
add a comment
|
That does not really solve OPs question - it only looks in the current directory and will only print regular files. Also will compare against 1Kb instead of 1MB. Finally we are after answers with some explanation about why the code works.
– grochmal
Jun 13 at 21:53
My bad added what it does.
– Vignesh SP
Jun 13 at 22:16
That does not really solve OPs question - it only looks in the current directory and will only print regular files. Also will compare against 1Kb instead of 1MB. Finally we are after answers with some explanation about why the code works.
– grochmal
Jun 13 at 21:53
That does not really solve OPs question - it only looks in the current directory and will only print regular files. Also will compare against 1Kb instead of 1MB. Finally we are after answers with some explanation about why the code works.
– grochmal
Jun 13 at 21:53
My bad added what it does.
– Vignesh SP
Jun 13 at 22:16
My bad added what it does.
– Vignesh SP
Jun 13 at 22:16
add a comment
|
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f524760%2fhow-to-sort-human-readable-size%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
-k 5
— how does that work?– ctrl-alt-delor
Jun 13 at 19:27
@ctrl-alt-delor: I believe the size is in the 5th column of the
ls
output– Jesse_b
Jun 13 at 19:30
2
Using
du
instead ofls
could be a good idea.– xenoid
Jun 13 at 19:34
... or
find
’s-printf
with its%p
and%s
formatters (followed by a “humanisation” of the sizes).– Stephen Kitt
Jun 13 at 19:35
@Jesse_b my error, I just assumed that the data in the question (marked as this is what I got) was the sorted input.I was wrong.
– ctrl-alt-delor
Jun 13 at 22:10