I want to find out the maximum, minimum and average file size along with their path. Incase a directory holds similar file sile (say 15kb,15kb) it should display the path of both files and its files size as once. without useing head and tail command can we generate the output.(if we use tail -n 2 it will produce last two lines, instead do we have any other alternative to do that. For instance,a directory holds 20 files of same size(say file1--10b ,file2--10b......file20--10b) instead of using tail -n 20command do we have any command that takes automatically those 20 files of same size.

My code :


if [ $# -ne 1 ]
    echo "please pass arguments" 

if [ -d $dir ]
    if [ -z "$(ls -1A -- $dir)" ]
        echo " directory exists but its empty" 
                printf "minimum file size: %s\n" 
                du $dir -hab | sort -n -r |tail -n 2
                 find "$dir" -type f -printf '%s %p\n' | sort -n -r | head -n 1 | {
                read -r size name
                printf "maximum file size: %d\n\t%s\n" "$size" "$name"

                printf "average file size: %s"
                du $dir -sk | awk '{s+=$1}END{print s/NR}'
        echo " directory doesn't exists"

my output is: $./filestats testdir

minimum file size:  
15  testdir/subdir3/subdir4/file3.txt
15  testdir/subdir1/file5.txt
maximum file size: 48
average file size: 60

the actual output should be as follows: $./filestats testdir

minimum file size: 15 
    maximum file size: 48
    average file size: 60

On a GNU system:

#! /bin/sh -
find "$1" -type f -printf '%s\0  %p\n\0' |
  awk -vRS='\0' '
    {getline file}
    {n++; sum += $0; files[$0] = files[$0] file}
    $0 < min || n == 1 {min = $0}
    $0 > max || n == 1 {max = $0}
    END {
      if (n)
        printf "min: %d\n%s\nmax: %d\n%s\naverage: %.17g\n", \
          min, files[min], max, files[max], sum/n

That's for file size (here regular files only with -type f), as opposed to disk usage. For disk usage, use %k or %b instead of %s in the argument to find's -printf.

That assumes $1 does not look like a find option or predicate (like -L, !, (, -name...).

$ that-script /usr/bin
min: 30

max: 11634832

average: 170653.62570735652
  • The code which you had posted is throwing an error. The message is: min: 15 max: 15 avg: 15. I will edit my code once again please have a look. – buddha sreekanth May 19 '15 at 6:58
  • @buddhasreekanth, I've added an example in the answer. Please try and copy-paste the code as-is and try again. – Stéphane Chazelas May 19 '15 at 14:18
  • I am facing the same problem again. There is no change in the output getting same error again and again as I mentioned in earlier comment. Could you please check my edited code and actual output what I've posted. – buddha sreekanth May 19 '15 at 14:29
  • Works fine here. Post your output on gist.github.com and refer to the link in a comment. – Otheus May 20 '15 at 15:54

I often find shell scripts somewhat clunky, so I wrote a Python script to do it:

import os
import sys

dir = "."
if len(sys.argv) > 1:

files = [os.path.join(f[0], x) for f in os.walk(dir) for x in f[2]]
filesWithSizes = [(f, os.stat(f).st_size) for f in files if os.path.exists(f)]

sizes = [f[1] for f in filesWithSizes]
maxSize = max(sizes)
minSize = min(sizes)
avgSize = 0
if len(sizes) > 0:
  avgSize = sum(sizes) / len(sizes)

maxFiles = [f[0] for f in filesWithSizes if f[1] == maxSize]
minFiles = [f[0] for f in filesWithSizes if f[1] == minSize]

print("Minimum file size: {}".format(minSize))
for f in minFiles:
  print("  " + f)
print("Maximum file size: {}".format(maxSize))
for f in maxFiles:
  print("  " + f)
print("Average file size: {}".format(avgSize))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.