web-dev-qa-db-fra.com

Comment séparer plusieurs fichiers en fonction de leur taille dans un sous-répertoire?

J'ai un tas de fichiers vidéo que je voudrais séparer en fonction de la taille du fichier que j'ai décidé.

Exemple:

Le dossier BB a 15 fichiers de différentes tailles.

J'ai des sous-dossiers comme:

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

Donc, au lieu de le faire manuellement, cela peut être fait via Bash ou un script.

J'ai une idée générale que la commande find et un correct si autrement pourrait fonctionner, mais je n'ai aucune idée de comment le script.

De toute façon, un cadre de programmation général serait:

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");}

Alors j'espère que c'est facile à faire. Ce qui précède n'était qu'une idée générale que j'aurais faite.

5
SIDDHARTH

Je suggère de boucler tous les fichiers du répertoire courant avec cette boucle for:

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

Vous avez demandé mégaoctet , si vous vouliez réellement 100/500 mebibyte utilise 104857600 et 524288000 en conséquence.

Si le répertoire contient d’autres fichiers et que vous souhaitez simplement traiter, par exemple, .avi fichiers, utilisez:

for i in *.avi; do …

Des explications

  • for i in *; do … ; done - boucle sur tous les fichiers du répertoire en cours
  • size=$(stat --printf="%s" "$i") - récupère la taille du fichier en octets avec stat et l'enregistre en tant que variable size
  • if A; then B; Elif C; then D; else E; fi - si A est vrai, faites B, sinon si C est vrai, faites D, sinon faites E
  • [ $size -lt X ] - vérifie si size est less than X
  • mv "$i" Y/ - déplace le fichier en cours de traitement dans le dossier Y
7
dessert

Vous pouvez faire ce genre de chose avec GNU find par exemple.

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

NOTES:

  • Si vous souhaitez déplacer des fichiers dans le même arbre (par exemple, A/, B/, C/ sont des sous-répertoires de BB), vous devrez donc empêcher find de rentrer dans ceux-ci, en utilisant -maxdepth ou -Prune par exemple.

  • Des précautions sont nécessaires en raison du comportement d'arrondissement de -size. Ce n'est pas un problème avec ce cas, mais par exemple, -size -1M arrondira tous les fichiers de moins de 1024 Ko à 1 M de sorte que seuls les fichiers vides correspondent.

Test avec des fichiers de la taille en kilo-octets pour plus de commodité:

$ 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

ensuite

$ 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'

donnant

$ 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
7
steeldriver