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 :

Accés direct dans un gros fichier ?


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 36
    Points : 24
    Points
    24
    Par défaut Accés direct dans un gros fichier ?
    Bonjour,

    Soit un gros fichier d'environ 90 000 lignes (mais ça peut varier légèrement) dans lequel j'ai besoin de récupérer le contenu d'un numéro de ligne déterminé aléatoirement

    En KSH, j'ai donc écrit le bout de code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
     
    #! /bin/ksh
     
    # Mon gros fichier
    fileEntree=$1
    # Nombre de ligne dans le fichier
    nbEntree=`cat $fileEntree | wc -l`
     
    # numéro de la ligne a atteindre
    numEntree=$RANDOM
    # Modulo
    let "numEntree %= $nbEntree"
     
    # récupération de la ligne par head et tail
    entree=`head -${numEntree} $fileEntree | tail -1`
    echo "entree = "$entree
    Ca marche bien mais le problème, c'est lent, bcp trop lent (2 secondes pour remonter la valeur).
    Or ce bout de code fonctionne dans un autre script et au total, ca met 48h ! (Si je le désactive, ca ne mets "que" 4h)

    Je cherche donc une autre méthode plus rapide.

    J'ai envisagé de mettre le fichier dans un tableau ksh mais comme la taille du tableau est limité à 4096, ca ne marche pas.

    Est-ce qu'il existe une méthode ou fonction du côté de perl ou awk ou ... pour faire un accés direct dans un fichier à partir du numéro de ligne ?

    D'avance merci

  2. #2
    Membre confirmé Avatar de Tchetch
    Inscrit en
    Mars 2002
    Messages
    401
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 401
    Points : 477
    Points
    477
    Par défaut
    Est-ce que tu peux connaitre la position en terme d'octet, tu peux faire en C (mais il dois y avoir un équivalent en Perl, PHP, ...) fopen et fseek.
    Mais tu t'en sortiras mieux avec un script en Perl et une boucle ou un programme compilé que en shell. Là tu lances plusieurs processus, ça coûte du temps au système tout ça.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 36
    Points : 24
    Points
    24
    Par défaut
    Bonjour,

    Hélas non, je n'ai pas trop la possibilité de connaitre la position en terme d'octets : les lignes sont de 2 tailles différentes (8 ou 11 caractères)

    Je vais voir si du coté Perl, il y a une solution.

  4. #4
    Membre confirmé Avatar de Tchetch
    Inscrit en
    Mars 2002
    Messages
    401
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 401
    Points : 477
    Points
    477
    Par défaut
    Code perl : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    my $i = 0;
     
    #ouvre fichier et compte les lignes
    open FILE, "/tmp/file.txt";
    while(<FILE>) {
        $i++;
    }
     
    # retour au debut
    seek FILE, 0, SEEK_SET;
     
    # autres operations necessaires
     
    close FILE;

  5. #5
    Expert éminent sénior 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 : 47
    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
    Points : 12 262
    Points
    12 262
    Par défaut
    le plus simple tu random un n° de ligne

    mais tu ne cherche que cette ligne !

    sed -e "'$numero'p" fichier
    ou
    sed -e "'$numeroligne'!d" fichier
    pour(gnu sed)
    c'est ce qui sera le plus rapide.
    sur un fichier dump de 24Go ça prend 3 secondes 5 seulement pour des lignes de 21935055 caracteres en en plus là c'est en écrivant un fichier de sortie...


    sur un fichier de 90000lignes de 512 caractères tu peux diviser par 4 au moins...je pense en tout cas ça vaut le coup de tester.


    appora/exports2 > time sed -e "450p" vbresd.dmp > /tmp/toto

    real 0m0.65s
    user 0m0.06s
    sys 0m0.09s
    /appora/exports2 > ls -lrt vbresd.dmp
    -rw-rw-r-- 1 dbvbresd dba 4063232 Sep 9 18:01 vbresd.dmp

    /appora/exports2 > time sed -e "450p" bbresd.dmp > /tmp/toto

    real 0m3.57s
    user 0m0.44s
    sys 0m0.32s
    /appora/exports2 > ls -lrt bbresd.dmp
    -rw-rw-r-- 1 dbbbresd dba 23736320 Sep 9 18:01 bbresd.dmp
    /appora/exports2 > wc -c /tmp/toto
    21935055 /tmp/toto

    voilà le test avec des lignes de moins de 128 caractères :
    /tmp > i=0
    /tmp > while [ $i -lt 90000 ] ; do echo "ssssssssssssssssssssssssssssss[......]ssssssssssssssssssssssssssss\n" > toto ; i=$(($i + 1)) ; done
    /tmp > wc -l toto
    180000 toto
    /tmp > time sed -e "450!d" toto


    real 0m0.14s
    user 0m0.12s
    sys 0m0.03s
    /tmp >
    beaucoup plus rapide que je pensais même...

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 36
    Points : 24
    Points
    24
    Par défaut
    Bonjour,

    Effectivement, avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    entree=`sed -e "$numEntree!d" ${fileEntree}`
    les performances sont vraiment bien meilleures.

    Et cela a le mérite d'être simple à mettre en place.

    Décidément, il y aura toujours à apprendre avec sed ! (c'est bien dans les vieilles marmites que l'on fait les meilleures soupes !)

    Merci a tous

  7. #7
    Expert éminent sénior 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 : 47
    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
    Points : 12 262
    Points
    12 262
    Par défaut
    sed avec une belle regexp est une commande unique de traitement par lot,

    au lieu de trois si tu fais un cat un head et un tail + les deux pipes soit 5 éléments ....

    le choix est vite fait....
    le gros inconveignant, c'est peu simple, en ça peut parfois manquer de souplesse...

    des scripts sed de 40 lignes.... c'est quasi illisible même quand on connait pas si mal.....en cas de besoin de mise à jour il est plus simple de le réecrire completment que d'essayer de comprendre ce qu'on a fait y'a six moi...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/12/2009, 11h57
  2. Réponses: 5
    Dernier message: 23/07/2009, 19h49
  3. Accès direct dans Collection
    Par ttttnht dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 15/10/2008, 11h57
  4. Recherche rapide dans un gros fichier excel
    Par cyberboy00 dans le forum Macros et VBA Excel
    Réponses: 16
    Dernier message: 16/04/2008, 14h56
  5. Remplacer une chaîne de caractère dans un gros fichier
    Par dosilbr dans le forum Autres Logiciels
    Réponses: 3
    Dernier message: 06/03/2007, 13h38

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