Como armazenar informações de arquivos em uma matriz?

1

Com essa parte do script, posso obter as informações necessárias sobre os arquivos no meu diretório (e subdiretórios). A única informação que preciso é a extensão e o tamanho do arquivo.

for file in 'find . -type f'; do
   size=$(stat -c '%s' ${file})
   file=$(echo "${file}" | awk -F/ '{print $NF}')
   ext=$(echo "${file}" | grep '..*\.' | awk -F. '{print $NF}' | grep '[A-Za-z0-9]')
if [ -z ${ext} ]; then
   echo "NOTE: no extention"
else
   EXTS="${EXTS}${ext}${newLine}"

É apenas parte do roteiro. Então, minha pergunta é: como posso colocar este informação em uma matriz? Quer dizer, eu quero uma matriz com elementos para ficar assim:

 c/123 /12 h/90 /0 txt/0

onde c, h e txt são extensão de arquivo e 123, 12 e 0 são tamanhos de arquivos. Então, ultimamente, posso trabalhar separadamente com tamanhos e extensões
Eu espero que eu coloquei a minha pergunta. Desculpe por erros. :)

    
por user205638 27.03.2016 / 23:52

2 respostas

1

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
    
por muru 28.03.2016 / 00:40
1

Aqui está um pequeno script que está fazendo o trabalho:

i=0
while read -r -d $'
i=0
while read -r -d $'%pre%' file
do
   size=$(stat -c '%s' ${file})
   ext='basename $file | sed -re "s/^[^.]+.*\.//"'

   if [ -z "$ext" ] || [ "$ext" = "'basename $file'" ] ; then
      echo "NOTE: no extention ($file)"
   else
     extensions[$i]="$ext"
     sizes[$((i++))]=$size
   fi
done < <(find . -type f -print0)

for (( j=0 ; j<i; j++ )) do
  echo index: $j / extension: ${extensions[$j]} / size: ${sizes[$j]}
done
' file do size=$(stat -c '%s' ${file}) ext='basename $file | sed -re "s/^[^.]+.*\.//"' if [ -z "$ext" ] || [ "$ext" = "'basename $file'" ] ; then echo "NOTE: no extention ($file)" else extensions[$i]="$ext" sizes[$((i++))]=$size fi done < <(find . -type f -print0) for (( j=0 ; j<i; j++ )) do echo index: $j / extension: ${extensions[$j]} / size: ${sizes[$j]} done
    
por cmks 28.03.2016 / 02:11