Primeiro, não faça for file in $(find …)
. Isso é muito frágil.
Agora, você pode simplificar um pouco seu código obtendo a localização para imprimir os nomes de arquivo e tamanhos juntos, usando -printf
:
find . -type f -printf '%s.%f/'
Em seguida, você pode usar awk
para processar essa saída para obter tamanhos cumulativos por extensão. Observe que usei .
para separar o nome do arquivo ( %f
) do tamanho ( %s
) e adicionei um /
depois disso. Portanto, posso usar .
como um separador de campo em awk
. E como os únicos caracteres não permitidos em nomes de arquivos são /
e ASCII NUL, posso usar com segurança /
como o separador de registro.
Então:
awk -F. -v RS=/ 'NF > 2 {size[$NF] += $1; next}
{size["/"] += $1}
END {for (i in size) {print i,"/",size[i]}'
Aqui, estou usando /
como o índice, se não houver extensão.
Combinado:
$ find . -type f -printf '%s.%f/' | awk -F. -v RS=/ 'NF > 2 {size[$NF] += $1; next}
{size["/"] += $1}
END {for (i in size) {printf "%s/%d\n", i, size[i]}}'
h/780
md/2509
tex/23961
c/13557
//5109
txt/2349291
sh/1166
py/12248
Agora, se suas extensões não contiverem espaços, você poderá fazer:
my_array=( $(find . -type f -printf '%s.%f/' | awk -F. -v RS=/ 'NF > 2 {size[$NF] += $1; next} {size["/"] += $1} END {for (i in size) {printf "%s/%d\n", i, size[i]}}') )
Você também pode usar a substituição de processos e ler cada entrada em:
my_arr=()
while IFS='' read -r entry
do
my_arr+=( "$entry" )
done < <(find . -type f -printf '%s.%f/' | awk -F. -v RS=/ 'NF > 2 {size[$NF] += $1; next} {size["/"] += $1} END {for (i in size) {printf "%s/%d\n", i, size[i]}}')
Como antes:
$ printf "%s\n" "${my_arr[@]}"
h/780
md/2509
tex/23961
c/13557
//5109
txt/2349291
sh/1166
py/12248