Como eu mediria o tamanho dos arquivos em um diretório?

1

Eu tenho uma pasta cheia de arquivos de 600GB. Eu quero copiar automaticamente os primeiros 300 para uma pasta e o resto para outra pasta. Não tenho certeza de como limitar os resultados com ls ou o que for para que eu possa passar isso como um argumento ...

a plataforma é linux ...

edit: eu quero mover 300gb, não os primeiros 300 arquivos. Os tamanhos dos arquivos são arbitrários e a ordem não importa.

    
por Bill Gray 30.07.2009 / 17:35

9 respostas

5

Atualização: Ah, os primeiros 300GB, bem então ... isso provavelmente lento, dependendo do tamanho do arquivo, mas eu gosto do exercício: -)

filesize=0
for i in *; do 
    filesize=$(stat -c "%s" "$i");  
    (( totalsize += filesize )); 
    if [[ $totalsize < 322122547200 ]]; then
        mv "$i" first_300/
    else
        mv "$i" the_rest/
    fi
done

Espero que não haja problemas com o tamanho do int.

Se você quer dividi-las em pastas, cada uma com 300 arquivos, talvez você queira algo como o seguinte:

folder=0
counter=0
for i in *; do 
    mv $i foo_$folder/
    if [[ $(( counter % 10 )) -eq 0 ]]; then 
       (( folder++ ));
    fi
    (( counter++ ))
done

Embora isso possa não ser tão rápido quanto alguns dos comandos find. Se você quer apenas fazer o primeiro comando de 300, você pode usar a mesma estratégia de contador, mas usar um tempo de $ 300.

    
por 30.07.2009 / 18:07
2

Esta é uma maneira de obter uma distribuição quase igual de 300gb,

Você pode fazer uma pesquisa com base em du para encontrar a distribuição em diretórios e arquivos de nível superior e, em seguida, dividi-los em quase duas partes com algumas tentativas.

find . -maxdepth 1 -type d -exec du -sk {} \; | sort -n -k 1 > list.txt

Isso fornecerá uma lista classificada de KB tamanhos.
Você poderia fazer um truque como pegar linhas alternativas nesta lista para uma distribuição quase uniforme e rápida

awk '{if (FNR%2==1) print $2}' list.txt > list1.txt
awk '{if (FNR%2==0) print $2}' list.txt > list2.txt

Uma distribuição muito grosseira ...

Finalmente, se você tiver tamanhos de arquivos ou diretórios muito desiguais - muito longe da distribuição de 300 GB,
mantenha-se longe do problema bin-packing e faça algumas tentativas simples para se movimentar em torno de um casal de linhas entre os dois arquivos de lista.
Encontre a diferença entre os dois conjuntos (com du ) e mova um diretório / arquivo
isso é cerca de metade da diferença da lista maior para a menor.
Isso deve te deixar bem perto

    
por 30.07.2009 / 17:56
1

Você pode fazer isso com encontrar , cabeça & xargs . Deve ficar assim:

find ./ -type f -print0 | head -300 | xargs -0 -I mv {} /one/folder
find ./ -type f -print0 | xargs -0 -I mv {} /another/folder
    
por 30.07.2009 / 17:46
1

ATENÇÃO! Quando você começa a calcular tamanhos de arquivo, é provável que você cometa o erro de medi-los por bytes, enquanto a maioria dos sistemas de arquivos alocará espaço em disco em blocos. E esse tamanho de bloco varia de disco para disco, mas geralmente é um múltiplo de 512.

Basicamente, isso significa que você pode ter 500 arquivos de um byte cada, o que seria apenas 500 bytes. Mas um sistema de arquivos que aloca 2048 bytes por bloco teria, portanto, cerca de 1 megabyte de espaço em disco. Sim, isso é muita sobrecarga.

Basicamente, você deve arredondar os tamanhos de arquivo obtidos pelo tamanho do bloco do sistema de arquivos usado. Dessa forma, você pode medi-los com mais precisão.

Então, novamente, quanta diferença poderia ser? Se o tamanho do bloco for 2048 bytes, a quantidade média de bytes "perdidos" será de 1 KB. Com 300 arquivos, isso exigiria mais de 300 KB em relação ao tamanho total. Você quer copiar 300 GB, mas quantos arquivos seriam? E os dois discos estão usando o mesmo sistema de arquivos com o mesmo tamanho de bloco?

De qualquer forma, a margem de erro depende do tamanho médio do arquivo. Se você tem muitos arquivos enormes, (música, imagens, binários) a margem de erro seria muito pequena. Se você tiver muitos arquivos pequenos (como scripts, fontes e arquivos de texto), a margem de erro pode facilmente adicionar outros 30 GB ao tamanho total do arquivo, que você não considerou ...

Assim, medir tamanhos de arquivo não é fácil ...

    
por 30.07.2009 / 19:55
0

Você pode obter uma listagem do uso de arquivos extraindo o tamanho de ls -l ou usando o comando du :

$ cd /dirwithlotsoffiles $ du -k *

Isso imprimirá uma lista do tamanho dos arquivos em kilobytes, seguido do nome do arquivo.

    
por 30.07.2009 / 17:52
0

A resposta "find" copia os primeiros 300 arquivos, não os primeiros 300 GB que eu entendo como solicitação.

Você pode experimentar o tar e suas opções de vários volumes

    
por 30.07.2009 / 17:55
0

Uma maneira bastante grosseira seria fazer o loop de arquivos ordenados por tamanho (ls -S) e simplesmente mover cada arquivo alternativo para um dos subdiretórios. Que tal isso:

#!/usr/bin/bash
dir1=path/to/dir1
dir2=path/to/dir2
a=0
for file in 'ls -1S'
do
  a='expr $a + 1'
  even='expr $a%2|bc'
  if [ $even -gt 0 ]
  then
    mv $file $dir1
  else
    mv $file $dir2
  fi
done

~

    
por 30.07.2009 / 18:17
0

Eu tenho medo que você provavelmente terá que sujar as mãos com alguns scripts aqui. Você pode facilmente obter uma lista de arquivos e seu tamanho usando o comando do terminal ls -l, você teria então que escrever um script que passa por essa lista e copia os arquivos um por um e mantém um contador para gravar o número de arquivos. KB transferido até agora. A cada verificação, verifique se estamos com o valor de 300 GB, se não, mova outro arquivo. É provavelmente capaz de fazer em cerca de 10 linhas de Perl ou menos.

    
por 30.07.2009 / 18:19
0

Você pode obter um resultado razoável simplesmente obtendo uma lista de nomes de arquivos junto com o tamanho de cada arquivo. Classifique os arquivos de acordo com o tamanho maior primeiro. Em seguida, simplesmente copie o maior arquivo da lista que caberá no espaço restante no diretório de destino e remova-o da lista. Repita até que não haja mais arquivos.

Em seguida, inicie novamente com um novo diretório de destino. Repita até a lista estar vazia.

    
por 30.07.2009 / 18:40

Tags