[UNIX] Eviter le swap d'un sed ?

Jeef -  
 Jeef -
Bonjour,

j'ai fais un script qui traite un fichier de 400Mo de texte (dit "data"), soit environ 510.000 lignes
Et dans ce fichier je dois remplacer 300 chaines de caractère par 300 autres chaines (pour modifier des url, chacune étant différente (et il peut y avoir plusieurs occurrences de la chaine dans le "data").

J'ai donc mon fichier "data" et un autre fichier "liste" ayant comme structure
ancien1;nouveau1
ancien2;nouveau2
....

Je fais donc un awk pour boucler sur "liste" et pour chaque je fais un sed sur "data".

C'est fonctionnel à l'heure actuelle mais c'est un peu lent : 2h30 pour finir les 300 x 510.000 = 153.000.000 tours ...

J'ai remarqué qu'il y a un fichier "sedYh7tR" (par exemple) qui est créé dans le répertoire ou je lance le script.

Comme je fais un sed -i est-ce lié à ça (fichier temporaire qui a la fin remplace le fichier source) ?
ou est ce que c'est un fichier de swap ?
Avez vous une piste pour optimiser le script ?
J'avais pensé à faire un RAMDisk mais c'est pas évident à faire ...


Merci d'avance pour votre aide !
A voir également:

4 réponses

zipe31 Messages postés 38797 Date d'inscription   Statut Contributeur Dernière intervention   6 435
 
Salut,

J'ai remarqué qu'il y a un fichier "sedYh7tR" (par exemple) qui est créé dans le répertoire ou je lance le script.
Comme je fais un sed -i est-ce lié à ça (fichier temporaire qui a la fin remplace le fichier source) ?

Pas à la fin, à chaque fois que "sed -i" est appelé ;-(

Pour optimiser le temps, je pense qu'il faut que tu te tournes vers "Perl".


Par contre pourquoi ne pas modifier ton fichier liste en :
s/ancien1/nouveau1/
s/ancien2/nouveau2/

Avec une commande du genre :
sed -i 's#^#s/#;s#;#/#;s#$#/#' liste

et l'appeler ensuite comme suit :

sed -i -f liste data

Ça devrait déjà réduire le nombre de processus et d'instance de sed, non ?

0
lami20j Messages postés 21644 Statut Modérateur, Contributeur sécurité 3 570
 
Salut,

Peux tu m'envoyer par mail ou mettre sur cjoint un fichier de soit disant 5Mo et dire aussi ce que tu veux remplacer?
L'histoire d'essayer optimiser.

GNU/Linux:Linux is Not Ubuntu! Quel linux choisir ne veut pas dire votre Distribution préférée,
106485010510997108
0
Jeef
 
Bonjour et Merci pour vos réponse :)

en fait le problème de lenteur vient bien de l'écriture sur le disque car si je fais ça avec un sed ou avec un awk, le temps d'execution est identique ...

par exemple
awk '{gsub("ancien1","nouveau",$0); print }' fichier.xml > testAWK
me prend 20 secondes et créé un fichier de 500Mo (même taille que fichier.xml)

le sed prend le même temps en créant un fichier temporaire (à cause de l'option -i)

si je fais afficher à l'écran
awk '{gsub("ancien","nouveau",$0); print }' fichier.xml
ça prend ... j'ai pas eu la patience d'attendre jusqu'au bout ... :)


du coup est ce qu'on peux travailler en mémoire autrement qu'en C ?
Parce que je n'ai vraiment pas moyen de diminuer le nombre de boucles ...
0
zipe31 Messages postés 38797 Date d'inscription   Statut Contributeur Dernière intervention   6 435
 
Comme l'a précisé lami20j dans son message précédent, la possibilité de tester sur une copie des fichiers d'origine serait un petit plus pour nous ;-\

Sinon, as-tu testé ma proposition ?
A savoir faire un fichier-script pour sed à partir de ta liste et de ne lancer qu'une requête "sed" ?
0
lami20j Messages postés 21644 Statut Modérateur, Contributeur sécurité 3 570
 
Salut,

Parce que je n'ai vraiment pas moyen de diminuer le nombre de boucles ...

Peut être qu'il n'y a même pas besoin des boucles ;-)

J'ai donc mon fichier "data" et un autre fichier "liste" ayant comme structure
ancien1;nouveau1
ancien2;nouveau2
....


Ben, moi je n'ai rien ;-)

Donc envoi des exemples de fichier data et aussi le fichier liste et dit ce que tu veux remplacer et on testera.
Idéal serait d'avoir un fichier data exact (environ 5-8 Mo) et le fichier liste complet.

SI confidentiel ET tu penses que tu peux me faire confiance ALORS 
  tu peux l'envoyer par mail. 
SI confidentiel ET tu penses que tu ne peux pas me faire confiance ALORS 
  je vais passer un week end tranquil ;-) 
SI pas confidentiel ALORS
  envoye ces fichiers ;-)
  je vais regarder ce soir
FIN SI
0
Jeef
 
Merci à tous les deux :-D

Effectivement en transformant le fichier liste en fichier de commande sed ça fonctionne mais le comportement est identique (fichier "swap") et le temps d'exécution n'est pas amélioré de façon mesurable...
logique vu qu'on évite "que" 300 boucles sur les millions au total ...

Le soucis c'est que les fichiers sont confidentiels (données perso d'utilisateurs du boulo) donc je ne peux pas vous les envoyer :-\

Visiblement on peux faire un ramdisk comme ça :
# mkdir /mnt/ram
# mount -t tmpfs -o size=1000M none /mnt/ram

je vais tester ce we pq là j'ai pas le compte root pour le faire sur le serveur et mon poste de travail est tout pourri donc c'est mort avec un live CD Ubuntu :-(

je vous dirai ce qu'il en est !

en tout cas merci pour vos réponses
0