Como separar vários arquivos com base no tamanho do arquivo em um subdiretório?

5

Eu tenho um monte de arquivos de vídeo que eu gostaria de separar com base no tamanho do arquivo que eu decidi.

Exemplo:

A pasta BB tem 15 arquivos de vários tamanhos de arquivo.

Eu tenho a subpasta definida como:

  1. less than 100 MB -- folder A
  2. 100 MB to 500 MB -- folder B
  3. more than 500 MB -- folder C

Então, em vez de fazer manualmente, pode ser feito via Bash ou um script.

Eu tenho uma ideia geral de que o comando find e um apropriado, se mais, funcionariam, mas não têm idéia de como fazer o script.

De qualquer forma, um quadro de programação geral seria:

float _size=[file_size]; // Reads the file size

if(_size<100)    // File size is less than 100 MB
  {  exec mv [file] /A/* ; // Move to folder A }
else if(_size>500) // File size is greater than 500 MB
  {  exec mv [file] /C/* ; // Move to folder C }
else if((_size<=500)||(_size>=100)) //file size is between 100 to 500
  {  exec mv [file] /B/* ; // Move to folder C}
else
  {print("file error");}

Então, espero que seja fácil de fazer. O acima foi apenas uma ideia geral que eu teria feito.

    
por SIDDHARTH 07.10.2017 / 17:12

2 respostas

7

Sugiro fazer um loop sobre todos os arquivos no diretório atual com este for loop:

for i in *; do
  size=$(stat --printf="%s" "$i")
  if [ $size -lt 100000000 ]; then
      mv "$i" A/
  elif [ $size -lt 500000000 ]; then
      mv "$i" B/
  else
      mv "$i" C/
  fi
done

Você solicitou Megabyte , se realmente queria 100/500 Mebibyte use 104857600 e 524288000 de acordo.

Se o diretório contiver outros arquivos e você quiser apenas processar, .avi arquivos, use:

for i in *.avi; do …

Explicações

  • for i in *; do … ; done - executa o loop em todos os arquivos no diretório atual
  • size=$(stat --printf="%s" "$i") - obtenha o tamanho do arquivo em bytes usando stat e salve-o como variável size
  • if A; then B; elif C; then D; else E; fi - se A for verdadeiro, B, senão se C for verdadeiro, D, senão E
  • [ $size -lt X ] - teste se size é l ess t han X
  • mv "$i" Y/ - move o arquivo atualmente processado dentro da pasta Y
por dessert 07.10.2017 / 17:24
6

Você pode fazer esse tipo de coisa com o GNU find , por exemplo,

find BB/ -type f \( -size -100M -exec mv -t A/ {} + \
  -o -size +500M -exec mv -t C/ {} + -o -exec mv -t B/ {} + \)

NOTAS:

  • Se você quiser mover arquivos dentro da mesma árvore (por exemplo, A/ , B/ , C/ são subdiretórios de BB ), será necessário evitar find de recursão para estes, usando -maxdepth ou -prune por exemplo.

  • É necessário ter cuidado devido ao comportamento de arredondamento de -size . Não é um problema com este caso, mas, por exemplo, -size -1M arredondará todos os arquivos menores que 1024kB até 1M, de modo que apenas os arquivos vazios correspondam.

Teste com arquivos do tamanho de kilobytes por conveniência:

$ tree -h somepath/
somepath/
├── [   0]  file0
├── [100K]  file100
├── [150K]  file150
├── [200K]  file200
├── [250K]  file250
├── [300K]  file300
├── [350K]  file350
├── [400K]  file400
├── [450K]  file450
├── [ 50K]  file50
├── [500K]  file500
├── [550K]  file550
└── [600K]  file600

0 directories, 13 files

então

$ find somepath/ -type f \( -size -100k -exec mv -vt A/ {} + \
>   -o -size +500k -exec mv -vt C/ {} + -o -exec mv -vt B/ {} + \)
'somepath/file50' -> 'A/file50'
'somepath/file0' -> 'A/file0'
'somepath/file550' -> 'C/file550'
'somepath/file600' -> 'C/file600'
'somepath/file250' -> 'B/file250'
'somepath/file200' -> 'B/file200'
'somepath/file100' -> 'B/file100'
'somepath/file300' -> 'B/file300'
'somepath/file500' -> 'B/file500'
'somepath/file350' -> 'B/file350'
'somepath/file450' -> 'B/file450'
'somepath/file400' -> 'B/file400'
'somepath/file150' -> 'B/file150'

dando

$ tree -h A B C
A
├── [   0]  file0
└── [ 50K]  file50
B
├── [100K]  file100
├── [150K]  file150
├── [200K]  file200
├── [250K]  file250
├── [300K]  file300
├── [350K]  file350
├── [400K]  file400
├── [450K]  file450
└── [500K]  file500
C
├── [550K]  file550
└── [600K]  file600

0 directories, 13 files
    
por steeldriver 07.10.2017 / 19:17