Recursively list all of the files in a directory, group them by extension and calculate the average of the file sizes in each group

ls -r | ?{-not $_.psiscontainer} | group extension | select name, count, @{n='average'; e={($ | measure -a length).average}} | ft -a @{n='Extension'; e={$}}, count, @{n='Average Size (KB)'; e={$_.average/1kb}; f='{0:N2}'}
Here's an annotated version of the command, using full-names instead of aliases. It is exactly equivalent to the short-hand version. # Recursively list all the files in the current directory. Get-ChildItem -Recurse | # Filter out the sub-directories themselves. Where-Object { return -not $_.PsIsContainer; } | # Group the resulting files by their extensions. Group-Object Extension | # Pluck the Name and Count properties of each group and define # a custom expression that calculates the average of the sizes # of the files in that group. # The back-tick is a line-continuation character. Select-Object ` Name, Count, @{ Name = 'Average'; Expression = { # Average the Length (sizes) of the files in the current group. return ($_.Group | Measure-Object -Average Length).Average; } } | # Format the results in a tabular view, automatically adjusted to # widths of the values in the columns. Format-Table -AutoSize ` @{ # Rename the Name property to something more sensible. Name = 'Extension'; Expression = { return $_.Name; } }, Count, @{ # Format the Average property to display KB instead of bytes # and use a formatting string to show it rounded to two decimals. Name = 'Average Size (KB)'; # The "1KB" is a built-in constant which is equal to 1024. Expression = { return $_.Average / 1KB }; FormatString = '{0:N2}' }
Sample Output
Extension Count Average Size (KB)
--------- ----- -----------------
.js          29              4.70
.txt          1              0.14
.chm          1            666.80
.dll          1             40.00
.xml          1             75.79
.html         8              1.25

2012-03-13 17:58:10

These Might Interest You

  • It will print a compact ls -la list with the directories at the beginning. --almost-all - do not list implied . and .. --group-directories-first - group directories before files --color - colorize the output --no-group - in a long listing, don't print group names --human-readable - print human readable sizes (e.g., 1K 234M 2G) --classify - append indicator (one of */=>@|) to entries If you want to see the owner: ls -l --almost-all --group-directories-first --color --no-group --human-readable --classify Show Sample Output

    ls -g --almost-all --group-directories-first --color --no-group --human-readable --classify
    icatalina · 2016-04-15 17:12:35 0
  • Interacting with Active Directory to add users from one group to another group. This prevents from having to deal with long DNs and copying, pasting problems. It executes once per returned object.

    for /F "DELIMS=""" %i in ('dsquery group -name SourceGroupName ^| dsget group -members') do dsquery group -name TargetGroupName | dsmod group -addmbr %i
    miketheman · 2009-09-25 16:32:33 0
  • PmWiki stores wiki pages as Group.Name. Simply split the directory listing and count frequency of group occurances. Show Sample Output

    cd /path/to/pmwiki/wiki.d;/bin/ls -1 | perl -ne 'my ($group,$name)=split(/\./);$counts{$group}++;' -e 'END { foreach $group (sort keys %counts) {printf("%d\t%s\n",$counts{$group},$group);} }'|sort -rn
    tamouse · 2011-09-14 19:33:39 0
  • It's change the group id of all the files on your system that have the OLDGID group as the owner group by the new NEWGID. But first do this: Document which files will be changed, use: find / -gid OLDGID ! -type l > resplado-gid.txt Be sure to disconnect users from the old group. Stop demons or services associated with the group. Be sure the new group exist and take note of GID

    $ find / -gid OLDGID ! -type l -exec chgrp NEWGID {} \;
    rcorrea · 2017-08-09 21:37:51 0

What Others Think

I'd be interested to see how you would do this in a linux shell, especially if you can do it without perl or python.
brianpeiris · 323 weeks and 5 days ago
for brianpeiris: for extension in $(find . -type f -name "*.*" | awk -F. '!a[$NF]++{print $NF}'); do echo $extension; matches="$(find . -type f -name "*.$extension" -execdir stat -c%s '{}' \;)"; echo 0 $(echo $matches | tr '\n' '+') $(echo $matches | wc -l) / p | dc; done
ysangkok · 274 weeks and 4 days ago

What do you think?

Any thoughts on this command? Does it work on your machine? Can you do the same thing with only 14 characters?

You must be signed in to comment.

What's this? is the place to record those command-line gems that you return to again and again. That way others can gain from your CLI wisdom and you from theirs too. All commands can be commented on, discussed and voted up or down.

Share Your Commands

Stay in the loop…

Follow the Tweets.

Every new command is wrapped in a tweet and posted to Twitter. Following the stream is a great way of staying abreast of the latest commands. For the more discerning, there are Twitter accounts for commands that get a minimum of 3 and 10 votes - that way only the great commands get tweeted.


Subscribe to the feeds.

Use your favourite RSS aggregator to stay in touch with the latest commands. There are feeds mirroring the 3 Twitter streams as well as for virtually every other subset (users, tags, functions,…):

Subscribe to the feed for: