Como encontrar tamanho máximo e mínimo de arquivo junto com seu caminho em um diretório

1

Eu quero descobrir o tamanho máximo, mínimo e médio do arquivo junto com o caminho deles. Incase um diretório contém sile arquivo similar (digamos 15kb, 15kb) deve exibir o caminho de ambos os arquivos e seu tamanho de arquivos como uma vez. sem usar o comando head e tail , podemos gerar a saída (se usarmos tail -n 2 , produziremos as últimas duas linhas, em vez disso, temos outra alternativa para fazer isso. Por exemplo, um diretório contém 20 arquivos de mesmo tamanho (digamos file1--10b, file2--10b ...... file20--10b) ao invés de usar o comando tail -n 20 temos algum comando que tome automaticamente os 20 arquivos do mesmo tamanho.

Meu código:

#!/bin/bash
dir=$1

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

if [ -d $dir ]
then
    if [ -z "$(ls -1A -- $dir)" ]
      then
        echo " directory exists but its empty" 
        else
                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}'
    fi
        else
        echo " directory doesn't exists"
fi

minha saída é: $ ./filestats testdir

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

a saída real deve ser a seguinte:     $ . / filestats testdir

minimum file size: 15 
        testdir/subdir3/subdir4/file3.txt
        testdir/subdir1/file5.txt
    maximum file size: 48
        testdir/file7.txt
        testdir/file8.txt
    average file size: 60
    
por buddha sreekanth 04.05.2015 / 16:27

2 respostas

4

Em um sistema GNU:

#! /bin/sh -
find "$1" -type f -printf '%s
$ that-script /usr/bin
min: 30
  /usr/bin/rgrep
  /usr/bin/xlinks2

max: 11634832
  /usr/bin/doxygen

average: 170653.62570735652
%p\n
#! /bin/sh -
find "$1" -type f -printf '%s
$ that-script /usr/bin
min: 30
  /usr/bin/rgrep
  /usr/bin/xlinks2

max: 11634832
  /usr/bin/doxygen

average: 170653.62570735652
%p\n%pre%' | awk -vRS='%pre%' ' {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 }'
' | awk -vRS='%pre%' ' {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 }'

Isso é para o tamanho do arquivo (aqui regular arquivos apenas com -type f ), ao contrário do uso do disco. Para uso de disco, use %k ou %b em vez de %s no argumento para find ' -printf .

Isso pressupõe que $1 não se parece com uma opção ou predicado find (como -L , ! , ( , -name ...).

%pre%     
por 04.05.2015 / 17:03
1

Muitas vezes eu acho scripts shell um pouco desajeitados, então eu escrevi um script Python para fazer isso:

import os
import sys

dir = "."
if len(sys.argv) > 1:
  dir=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))
    
por 07.05.2015 / 09:00