![Como armazenar informações de arquivo em um array?](https://rvso.com/image/1087142/Como%20armazenar%20informa%C3%A7%C3%B5es%20de%20arquivo%20em%20um%20array%3F.png)
Com esta parte do script posso obter as informações necessárias sobre os arquivos em 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 dúvida é: Como posso colocar essas informações em um array? Quero dizer, quero que um array com elementos fique assim:
c/123 /12 h/90 /0 txt/0
onde c, h e txt são extensões de arquivo e 123, 12 e 0 são tamanhos de arquivo. Ultimamente, posso trabalhar separadamente com tamanhos e extensões.
Espero ter formulado minha pergunta de maneira organizada. Desculpe pelos erros. :)
Responder1
Primeiro,não façafor file in $(find …)
. Isso é muito frágil.
Agora, você pode simplificar um pouco seu código fazendo com que find imprima os nomes e tamanhos dos arquivos 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 eu costumava .
separar o nome do arquivo ( %f
) do tamanho ( %s
) e adicionei um /
depois disso. Portanto, posso usar .
como separador de campos em awk
. E como os únicos caracteres não permitidos em nomes de arquivos são /
ASCII NUL, posso usá-los com segurança /
como separador de registros.
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 í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ê poderia simplesmente 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]}}') )
Ou você pode usar a substituição de processo 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
Responder2
Aqui está um pequeno script bash que está fazendo o trabalho:
i=0
while read -r -d $'\0' 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