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
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?
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
Se você tiver ferramentas GNU:
find -maxdepth 1 -type f -printf '%s %pperl -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 %pperl -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%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
#!/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
Tags bash linux shell-script