help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Sorting directories by size


From: Kerin Millar
Subject: Re: Sorting directories by size
Date: Tue, 24 Aug 2021 15:40:39 +0100
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.13.0

On 24/08/2021 15:25, hancooper wrote:
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, August 24, 2021 2:20 PM, hancooper <hancooper@protonmail.com> wrote:

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, August 24, 2021 2:05 PM, Kerin Millar kfm@plushkava.net wrote:

On 24/08/2021 14:46, hancooper wrote:

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, August 24, 2021 1:35 PM, hancooper hancooper@protonmail.com wrote:

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, August 24, 2021 12:52 PM, Alex fxmbsw7 Ratchev fxmbsw7@gmail.com 
wrote:

i guess you didnt set $dir
On Tue, Aug 24, 2021, 14:12 hancooper hancooper@protonmail.com wrote:

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, August 24, 2021 3:31 AM, Kerin Millar kfm@plushkava.net
wrote:

On Tue, 24 Aug 2021 02:21:28 +0000
hancooper via help-bash@gnu.org wrote:

I have a directory stored in `dir`. I want to store the names of
directories at a particular level

and sort them by size.
I have started with listing the directory names in `dlc` and computing
the total number of

directories present. But still have to sort `dlc` by size, the with
the biggest first.

My initial plan is to use a command such as `du -h | sort -h`.
daggr=( -mindepth "$depth" -maxdepth "$depth" )
dlc=$( find "$dir" "${daggr[@]}" -type d | tr "\n" " " )
ndr=$( echo "$dlc;" | grep -o " " | wc -l )

The last two of these three commands should be jettisoned. Further, you
ought to be using an array to store the directory names. As you appear to
be using GNU, consider the following.
daggr=(-mindepth "$depth" -maxdepth "$depth")
mapfile -td '' dlc < <(find "$dir" "${daggr[@]}" -type d -exec du -0 {}

-   | sort -zrn | cut -z -f2-)

ndr=${#dlc[@]}
This relies on the fact that GNU du(1), given the -0 option, employs an
output format of "%d\t%s\0", <size>, <pathname>.
Kerin Millar

I agree with your assessment. Have seen that I get the following errer
find: ‘’: No such file or directory

I would like to have the capability to print the directories with their size,
in the form of a table (size dir).

Have used the following
sdr=$( find "$src" "${daggr[@]}" -type d -exec du {} + \
| sort -zrn )
echo "$sdr"

That's not what I wrote. The above is broken in multiple ways. Not
least, because du(1) no longer uses NUL as a line delimiter.

Have used what you wrote. But am also trying to do a print for users
as well. Have removed the `-0` to keep the results in the form of a
table.

I am suspicious of the sorted results because I get
bash: warning: command substitution: ignored null byte in input
17844 ./01cuneus/articles/detailed/advoc/privasec--2018/privasec--2018--files
18636 ./01cuneus/articles/detailed/advoc/privasec--2018
40812 ./01cuneus/articles/detailed/advoc/eucd
59452 ./01cuneus/articles/detailed/advoc
4 
./01cuneus/articles/detailed/infocs/geoinforma/2018--gsdcoll--esc/gsdcoll--esc--files
34584 ./01cuneus/articles/detailed/infocs/geoinforma/2018--gsdcoll--esc
35460 ./01cuneus/articles/detailed/infocs/geoinforma
272 ./01cuneus/articles/detailed/infocs/informatic--files/tempora
8348 ./01cuneus/articles/detailed/infocs/informatic--files
132 ./01cuneus/articles/detailed/infocs/ntwrk--survl
43944 ./01cuneus/articles/detailed/infocs
4 ./01cuneus/articles/short/advoc/opendm/2019/q2
8 ./01cuneus/articles/short/advoc/opendm/2019
12 ./01cuneus/articles/short/advoc/opendm

As above.

Finally, the display of the sorted list should show the size in
human readable form.

So you're happy for the output lines of du(1) to be stored by an array,
as opposed to just the pathnames? Very well.
mapfile -td '' dlc < <(find "$dir" "${daggr[@]}" -type d -exec du -h0 {}

-   | sort -zrh)
     --
     Kerin Millar


For the actual functionality I use only the array with the directory names.
But for display, I want the ability to show a table of sorted (size dirname).
With the size being printed in human readable form. For the display part,
I do not need to store the information in an array.

I see.


Have got almost what I'd like, except that tho sizes are not in human readable 
form.

find "$src" "${daggr[@]}" -type d -exec du {} + | sort -rn

This is easily defeatable if you are going to later rely on iterating over the directory names. You must exploit du -0 for any of this to be truly reliable. No ifs or buts. The following code will show the intended table.

mapfile -td '' lines < <(find "$dir" "${daggr[@]}" -type d -exec du -h0 {} | sort -zrh)
printf '%s\n' "${lines[@]}"

Having done so, you may iterate over the pathnames with the assistance of the following loop.

for line in "${lines[@]}"; do
    path=${line#*$'\t'}
    do_something_with "$path"
done

This works because of the well defined format of (GNU) du -0 that was mentioned by my initial response. By stripping all up to - and including - the first occuring tab character, it is guaranteed that only the exact pathname will remain. Of course, you could also use that same technique to compose a new array that contains only the pathnames.

paths=()
for line in "${lines[@]}"; do
    paths+=("${line#*$'\t'}")
done

--
Kerin Millar



reply via email to

[Prev in Thread] Current Thread [Next in Thread]