IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Optimisation - Découpage d'un fichier avec DD


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 4
    Par défaut Optimisation - Découpage d'un fichier avec DD
    Bonjour,

    Je fais appel à vos lumières pour une optimisation de script shell.
    Je vais essayer d'expliquer simplement mon besoin.

    D'où je pars:
    1. J'ai un fichier plat que je recois tous les jours
    2. Dedans il se présente de la manière suivante:
    a. Entete 'abcbdef000016345000028346'
    b. Image jpg dont la taille est de 16345 (taille préciser en entete)
    c. Image jpg dont la taille est de 28346 (taille préciser en entete)
    d. On recommence avec entete / image1 / image 2 (parfois plus de 10 000 fois)
    Ce que je dois faire:

    1. Prendre ce fichier
    2. Lire l'entete
    3. En fonction de la taille des images extraire chaque image et l'enregistrer.

    Jusqu'ici tout va bien. J'ai donc fais un script shell en utilisant la commande DD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dd bs=1 skip=$skip count=$tailledelimage if=$fichiersource of=$fichiersorti
    Cela fonctionne bien, j'arrive à extraire toutes les images
    Par contre dans le cadre de fichiers avec 10 000 enregistrements ca met énormément de temps, des heures en faite (4-5h)!

    Je cherche donc un moyen d'optimiser cela ou alors de trouver une alternative à la commande DD.
    J'ai essayer de jouer avec le paramètre bs mais ca ne fonctionne pas car il faut trouver le bon bs et adapter le skip et le count du coup!

    Je ne sais pas si c'est assez clair mais j'espère que des experts en shell pourront m'aider!

    Merci d'avance pour votre aide

  2. #2
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Par défaut
    concrètement j'aurais fait comme toi, parce que malgré le temps que ça prend, je ne vois pas comment faire autrement mais si une astuce fiable est proposée je suis preneur .

  3. #3
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Ca met du temps parce que tu donnes une taille de bloc de 1 octer. dd fait un read() et un write() par bloc, donc si tu as 1GB de données ça te fais 1 milliard d'appels à read() et un milliard d'appels à write().

    Tu as compris que dans ton cas ça allait d'être difficile ou impossible à optimiser avec dd, à cause de l'entête qu'il faut skipper et qui est toute petite.

    Le plus simple à mon avis serait de coder un truc en C pour extraire les images. Ca ne devrait pas être trop compliqué. Ou alors en Perl avec un unpack().

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Citation Envoyé par matafan Voir le message
    Ca met du temps parce que tu donnes une taille de bloc de 1 octer. dd fait un read() et un write() par bloc, donc si tu as 1GB de données ça te fais 1 milliard d'appels à read() et un milliard d'appels à write().
    Je vais peut être dire une c*nnerie, mais si on fait le contraire, un bloc de la taille de l'image ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dd bs=$tailledelimage skip=$skip count=1 if=$fichiersource of=$fichiersorti

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Dans ce cas on n'a effectivement une seule lecture et une seule écriture, mais le problème, comme l'a remarqué brucelili, c'est que le "skip" est aussi exprimé en nombre de blocs. Comme la taille à skipper est très faible (la taille du header), on a forcément une taille de bloc très faible.

    Et même si on enlevait le header avant de lire le fichier, on a encore un problème du même type pour accéder à la deuxième image et aux suivantes, puisques les deux types d'image n'ont pas la même taille. Il faut prendre comme taille de bloc le pgcd des deux tailles. Si on n'a pas de bol ça peut être 1...

    Au mieux on peut différencier ibs et obs, de façon à ne faire qu'une grosse écriture (skip est exprimé en ibs). Mais on devra toujours faire plein de petites lectures.

    Mais vraiment, en C, c'est trivial à faire et ça sera beaucoup plus rapide.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Citation Envoyé par matafan Voir le message
    Dans ce cas on n'a effectivement une seule lecture et une seule écriture, mais le problème, comme l'a remarqué brucelili, c'est que le "skip" est aussi exprimé en nombre de blocs. Comme la taille à skipper est très faible (la taille du header), on a forcément une taille de bloc très faible.
    Effectivement je n'avais pas fait le rapprochement avec le skip qui s'exprime aussi en fonction du bloc et jongler avec les z'obs et les z'ibs ne serait pas une sinécure

    Merci pour les explications

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 4
    Par défaut
    Merci pour vos réactions sur mon problème.
    Comme je m'en doutais il n'y a pas vraiment de solution en script shell.

    Etant donné que mon script est une petite application avec pas mal de fonctionnalité avec entre autre la fonctionnalité d'extraction de mon fameux fichier contenant des image, je pense étudier la proposition de matafan.

    Je pense faire un petit programme en C que j'appellerai dans mon script en passant en paramètre ce fichier.
    Cependant, je n'ai jamais trop pratiquer le C, Matafan pourrais-tu me donner quelques pistes pour démarrer le traitement de mon fichier.

    Merci d'avance pour ton aide.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 4
    Par défaut
    J'ai essayé...
    Ca marche pas car le skip aprés n'est plus bon.

    Mon skip s'incremente a achaque fois avec de la manière suivante:
    skip= $skip + $tailleEntete + $tailleImage1
    skip= $skip + $tailleEntete + $tailleImage2
    ...
    .....

    si je change le BS par la taille de l'image le skip n'est plus en phase avec la taille des blocks !

    Je vais peut etre me retrouner vers un bout de code en perl.
    Mais si quelqu'un à d'autres idées

Discussions similaires

  1. Aide pour découpage fichier avec awk
    Par Invité dans le forum Unix
    Réponses: 8
    Dernier message: 22/04/2011, 14h51
  2. Réponses: 8
    Dernier message: 14/11/2003, 22h51
  3. Dossier ou Fichier avec ShellListView
    Par MoussDiouf dans le forum Langage
    Réponses: 6
    Dernier message: 14/06/2003, 12h33
  4. [VB6] [Réseau] Récupérer la taille d'un fichier avec inet
    Par pcpunch dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 20/02/2003, 21h38
  5. enregistrer dans un fichier avec une appli mdi
    Par ferrari dans le forum C++Builder
    Réponses: 4
    Dernier message: 05/05/2002, 15h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo