arquivos maiores que um tamanho médio de diretório?

4

como eu poderia encontrar todos os arquivos e diretórios com tamanho maior ou igual ao tamanho médio do arquivo de o diretório atual?

    
por radha 26.01.2016 / 12:37

4 respostas

3

avg_size=$(find . -maxdepth 1 -type f -printf %s\n | 
  { sum=0; files=0; while read size; do sum=$((sum+size)); ((files++)); done; echo "$((sum/files))"; })
echo "average file size: ${avg_size}"
find . -maxdepth 1 -type f -size +"$avg_size"c
    
por 26.01.2016 / 13:07
2

Se você tiver ferramentas GNU:

find -maxdepth 1 -type f -printf '%s %p
perl -le 'opendir(D,"."); @F=readdir(D); @files=grep{-f $_}@F; 
    for (@files){$s= -s $_; $t+=$s; $f{$_}=$s} 
    print join "\n",grep{$f{$_}>=$t/scalar(@files)}@files' 
' | awk -v RS='
#!/usr/bin/perl 

## Open the current directory as D
opendir(D,".");
## Read the contents of D into @F
@F=readdir(D);
## Collect only the files, no dirs etc. 
@files=grep{-f $_}@F;
## For each file, as $_
for (@files){
    ## Get the size
    $s= -s $_;
    ## Add the size to the total
    $t+=$s;
    ## Save the size in the hash %f whose keys are the file names
    $f{$_}=$s
}
## Get all files whose size is greater than the average
my @wanted=grep{$f{$_}>=$t/scalar(@files)}@files;
## Print the elements of the array @wanted with a newline after each of them
print join "\n", @wanted ;
print "\n";
' '{a[$0]=$1;s+=$1;} END{m=s/NR; for(i in a){if(a[i]>=m){print i}}}'

E se você não fizer isso:

find -maxdepth 1 -type f -printf '%s %p
perl -le 'opendir(D,"."); @F=readdir(D); @files=grep{-f $_}@F; 
    for (@files){$s= -s $_; $t+=$s; $f{$_}=$s} 
    print join "\n",grep{$f{$_}>=$t/scalar(@files)}@files' 
' | awk -v RS='
#!/usr/bin/perl 

## Open the current directory as D
opendir(D,".");
## Read the contents of D into @F
@F=readdir(D);
## Collect only the files, no dirs etc. 
@files=grep{-f $_}@F;
## For each file, as $_
for (@files){
    ## Get the size
    $s= -s $_;
    ## Add the size to the total
    $t+=$s;
    ## Save the size in the hash %f whose keys are the file names
    $f{$_}=$s
}
## Get all files whose size is greater than the average
my @wanted=grep{$f{$_}>=$t/scalar(@files)}@files;
## Print the elements of the array @wanted with a newline after each of them
print join "\n", @wanted ;
print "\n";
' '{a[$0]=$1;s+=$1;} END{m=s/NR; for(i in a){if(a[i]>=m){print i}}}'

Que pode ser expandido para:

%pre%     
por 26.01.2016 / 13:24
1

Aqui está uma solução específica para o bash; ele faz um loop sobre os arquivos, reunindo seus tamanhos e nomes em uma matriz bash indexada, calcula a média e passa de volta pela matriz, imprimindo apenas os nomes de arquivos que são estritamente maiores que o tamanho médio (inteiro).

#!/bin/bash

declare -i sum=0
declare -i nfiles=0
declare -a filenames
declare -a filesizes

for file in *
do
  [ -f "$file" ] || continue
  size=$(stat -c %s -- "$file")
  filenames[$nfiles]="$file"
  filesizes[$nfiles]=$size
  sum+=$size
  nfiles+=1
done

[ $nfiles -eq 0 ] && exit

avg=$(( sum / nfiles ))

for((index=0; index < ${#filenames[*]}; ++index))
do
  [ ${filesizes[$index]} -gt $avg ] && printf "%s\n" "${filenames[$index]}"
done
    
por 26.01.2016 / 14:52
0
#!/bin/bash
no=$(ls -l | wc -l)
find_files(){
    if [ $(ls -l | awk '{print $5}' | awk 'FNR=='$1'') -ge $2 ]
    then
        echo $(ls -l | awk '{print $9}' | awk 'FNR=='$1'')
    fi
}

average(){
    local   count=2
    sum=0
    while [ $count -le $no  ]
    do
        let sum=sum+$(ls -l | awk '{print $5}' | awk 'FNR=='$count'')

        ((count++))
    done
    let num=$no-1
    let avg=$sum/$num
    echo $avg
}
main(){
    a=$(average)
    i=2
    while [ $i -le $no ]
    do
        find_files $i $a
        ((i++))
    d

}

main
    
por 06.02.2016 / 14:39