问题
What is the best practice for printing a top 10 list of largest files in a POSIX shell? There has to be something more elegant than my current solution:
DIR="."
N=10
LIMIT=512000
find $DIR -type f -size +"${LIMIT}k" -exec du {} \; | sort -nr | head -$N | perl -p -e 's/^\d+\s+//' | xargs -I {} du -h {}
where LIMIT is a file size threshold to limit the results of find.
回答1:
This uses awk
to create extra columns for sort keys. It only calls du
once. The output should look exactly like du
.
I've split it into multiple lines, but it can be recombined into a one-liner.
du -h |
awk '{printf "%s %08.2f\t%s\n",
index("KMG", substr($1, length($1))),
substr($1, 0, length($1)-1), $0}' |
sort -r | cut -f2,3
Explanation:
- BEGIN - create a string to index to substitute 1, 2, 3 for K, M, G for grouping by units, if there's no unit (the size is less than 1K), then there's no match and a zero is returned (perfect!)
- print the new fields - unit, value (to make the alpha-sort work properly it's zero-padded, fixed-length) and original line
- index the last character of the size field
- pull out the numeric portion of the size
- sort the results, discard the extra columns
Try it without the cut
command to see what it's doing.
Edit:
Here's a version which does the sorting within the AWK script and doesn't need cut (requires GNU AWK (gawk
) for asorti
support):
du -h |
awk '{idx = sprintf("%s %08.2f %s",
index("KMG", substr($1, length($1))),
substr($1, 0, length($1)-1), $0);
lines[idx] = $0}
END {c = asorti(lines, sorted);
for (i = c; i >= 1; i--)
print lines[sorted[i]]}'
来源:https://stackoverflow.com/questions/5213288/human-readable-recursive-sorted-list-of-largest-files