2009-05-09 4 views
1

J'ai un très gros fichier journal (9 Go - je sais que j'ai besoin de résoudre ce problème) sur ma boîte. Je dois diviser en morceaux afin que je puisse le télécharger sur Amazon S3 pour la sauvegarde. S3 a une taille de fichier maximale de 5 Go. Donc, je voudrais diviser cela en plusieurs morceaux, puis télécharger chacun d'eux.Comment diviser un fichier journal avec une valeur de décalage sous unix?

Voici la capture, j'ai seulement 5Go sur mon serveur gratuit, donc je ne peux pas faire un simple split unix. Voici ce que je veux faire:

  1. saisir le premier 4 Go du fichier journal et recracher dans un fichier séparé (appeler le segment 1)
  2. Ajouter que segment1 à s3.
  3. rm segment1 pour libérer de l'espace.
  4. Saisissez les 4 Go du milieu du fichier journal et téléchargez-les sur s3. Nettoyage comme avant
  5. Récupérez les 1 Go restants et téléchargez-les sur S3.

Je ne trouve pas la bonne commande Unix à diviser avec un décalage. Split ne fait que les choses en morceaux égaux et csplit ne semble pas avoir ce dont j'ai besoin non plus. Des recommandations?

Répondre

3

Une solution (convolutée) consiste à la compresser en premier. Un fichier journal textuel devrait facilement passer de 9G à bien en dessous de 5G, puis vous supprimez l'original, ce qui vous donne 9G d'espace libre.

Ensuite, vous dirigez ce fichier compressé directement via split afin de ne pas utiliser plus d'espace disque. Ce que vous finirez avec est un fichier compressé et les trois fichiers à télécharger.

Téléchargez-les, puis supprimez-les, puis décompressez le journal d'origine.

=====

Une meilleure solution est de simplement compter les lignes (disons 3 millions) et d'utiliser un script awk pour extraire et envoyer les pièces individuelles:

awk '1,1000000 {print}' biglogfile > bit1 
# send and delete bit1 

awk '1000001,2000000 {print}' biglogfile > bit2 
# send and delete bit2 

awk '2000001,3000000 {print}' biglogfile > bit3 
# send and delete bit3 

Puis, à l'autre extrémité, vous pouvez traiter bit1 par bit3 individuellement ou recombiner les:

mv bit1 whole 
cat bit2 >>whole ; rm bit2 
cat bit3 >>whole ; rm bit3 

et, bien sûr, ce fractionnement peut être fait avec l'une des les outils de traitement de texte standard sous Unix: perl, python, awk, head/tail combo. Cela dépend de ce que vous êtes à l'aise.

+0

Je ne sais pas pourquoi je n'ai pas pensé à compresser le fichier. Il est descendu à 622M et il était assez petit pour télécharger. – Ish

+0

C'est une bonne solution, Ish. On dirait que je pourrais avoir juste fermé mon piège après la première phrase :-) – paxdiablo

2

Tout d'abord, gzip -9 votre fichier journal.

Ensuite, écrire un petit script shell pour utiliser dd:

#!/bin/env sh 

chunk_size = 2048 * 1048576; #gigs in megabytes 
input_file = shift;  

len = `stat '%s' $input_file` 
chunks = $(($len/$chunk_size + 1)) 

for i in {0...$chunks} 
do 
    dd if=$input_file skip=$i of=$input_file.part count=1 bs=$chunk_size 
    scp $input_file.part servername:path/$input_file.part.$i 
done 

Je viens flac cela dans le dessus de ma tête, donc je ne sais pas si cela va fonctionner sans modification, mais quelque chose de très semblable à ceci est ce dont vous avez besoin.

+0

Merci, je ne savais pas à propos de la commande dd qui est utile. – Ish

2

Vous pouvez utiliser dd. Vous devrez spécifier bs (la taille de la mémoire tampon), sauter (le nombre de tampons à ignorer) et compter (le nombre de tampons à copier) dans chaque bloc.

Donc, en utilisant une taille de mémoire tampon de 10Meg, vous feriez:

# For the first 4Gig 
dd if=myfile.log bs=10M skip=0 count=400 of=part1.logbit 
<upload part1.logbit and remove it> 
# For the second 4Gig 
dd if=myfile.log bs=10M skip=400 count=400 of=part2.logbit 
... 

Vous pouvez également bénéficier de la compression des données que vous allez transférer:

dd if=myfile.log bs=10M skip=800 count=400 | gzip -c > part3.logbit.gz 

Il peut y avoir des méthodes plus respectueuses de .

dd a quelques défauts réels. Si vous utilisez une petite taille de tampon, elle fonctionne beaucoup plus lentement. Mais vous pouvez seulement sauter/chercher dans le fichier par multiples de bs. Donc, si vous voulez commencer à lire des données à partir d'un décalage de premier ordre, vous êtes dans un vrai violon. Quoi qu'il en soit, je m'égare.

+0

pourrait dd sauter les lignes ou par délimiteur? –

0

La division Coreutils crée des sections de sortie de taille égale, à l'exception de la dernière section. Je ne sais pas pourquoi je n'ai pas pensé à compresser le fichier.

split --bytes=4GM bigfile chunks 
+0

Il a dit dans sa question qu'il ne peut pas simplement exécuter split en raison de l'espace disque limité sur son serveur. –

Questions connexes