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 :

Edition de fichier volumineux


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Bragu Demon
    Homme Profil pro
    Intégrateur d'Explopitation
    Inscrit en
    Juin 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Intégrateur d'Explopitation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2013
    Messages : 125
    Par défaut Edition de fichier volumineux
    Bonjour,

    Je vous expose mon problème :

    je dispose de plusieurs fichiers (actuellement 33).
    Je cherche à détecter les lignes en anomalies pour les corriger.
    Toutes les lignes doivent faire 600 caractères de long et commencer par 3 lettres majuscule + $ (ex: ABC$ ou FYE$ ou FFF$)
    La commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    egrep  -vn  '^\w{3}\$*{596}'  fichier
    me permet de détecter ces lignes.
    Elles m'affichent sous cette forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nom_du_fichier:numero_de_ligne_en_erreur:contenu_de_la_ligne_en_erreur
    Je dispose d'un fichier avec une ligne en erreur, il fait 3,30 Go et contient 5 497 219 de lignes.
    Au total mes 33 fichiers font 37,24 Go pour 81 051 621 de lignes.

    Je souhaiterai pouvoir "réparer" ces fichiers, c'est à dire que la ligne en erreur soit à la suite de la ligne qui la précède.
    J'ai cherché pour supprimer les sauts de lignes qui ne seraient pas à la position 601, mais je ne m'en sorts pas

    Des idées ?

  2. #2
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 376
    Par défaut
    Bonjour,

    Ok, on sait que tes lignes doivent faire 600 caractères mais quels types de caractères, 1 octet ou variable (par exemple le é latin en utf8 est sur 2 octets) ?

    Ensuite, comment on répare une ligne automatiquement ?

    Après, coté idée, tu as des outils comme awk, sed, perl,...

  3. #3
    Membre confirmé Avatar de Bragu Demon
    Homme Profil pro
    Intégrateur d'Explopitation
    Inscrit en
    Juin 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Intégrateur d'Explopitation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2013
    Messages : 125
    Par défaut
    Ca viens d'un mainframe (zOs) avec une table de caractère en EBCDIC, c'est donc 1 caractère pour 1 octet.

    Actuellement j'ai ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ligne_en_erreur=`egrep -nv '^\w{3}\$*{596}' $fichier | cut -d':' -f1`
    ligne_precedente=$(($ligne_en_erreur - 1))
    ligne_reparee=`sed -n ${ligne_precedente},${ligne_en_erreur}p $fichier | tr "\n" "\ "`
    Le problème c'est que je dois remettre tout ça dans le fichier et à la bonne ligne.

    Les lignes ont se format :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DEB$C005$E$2$    $    $0000000000$0999999999$ACTIVE $2017-01-06$2016-09-02$
    DET$C005$D$0005497216$C$721
    FIN$C005$F$000000005497218$
    Chaque ligne à le caractère $ comme séparateur de champ.
    Le 1er champ sert à définir le type de ligne
    Le 5ème champ représente le numéro de la ligne.

    On pourrait donc imaginer de recopier la ligne_reparee à la fin puis de trier le fichier par ordre croissant sur le 5ème champ, mais je ne sais simplement pas faire.

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Euh... c'est pas complètement clair pour moi...

    L'idéal serait que tu nous montres ce que tu appelles la ligne en erreur, ainsi qu'un peu de contexte (quelques précédentes et suivantes), par exemple de la manière suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    egrep  -vn -C2  '^\w{3}\$*{596}'  fichier # 2 lignes avant et 2 lignes après
    et également, afin qu'on voie la nature des fins de ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    egrep  -vn -C2  '^\w{3}\$*{596}'  fichier | od -c
    Puis que tu nous montres comment tu voudrais voir le bloc corrigé.

    Citation Envoyé par Bragu Demon Voir le message
    Je souhaiterai pouvoir "réparer" ces fichiers, c'est à dire que la ligne en erreur soit à la suite de la ligne qui la précède.
    J'ai cherché pour supprimer les sauts de lignes qui ne seraient pas à la position 601, mais je ne m'en sorts pas
    Citation Envoyé par Bragu Demon Voir le message
    Actuellement j'ai ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ligne_en_erreur=`egrep -nv '^\w{3}\$*{596}' $fichier | cut -d':' -f1`
    ligne_precedente=$(($ligne_en_erreur - 1))
    ligne_reparee=`sed -n ${ligne_precedente},${ligne_en_erreur}p $fichier | tr "\n" "\ "`

    D'après ce que tu dis, j'ai l'impression que certaines lignes sont "coupées", avec un CR ou un LF en trop, et qu'il faut raccorder les bouts.

    Mais, si c'est bien ça, alors tu devrais avoir DEUX lignes consécutives avec moins de 600 caractères, non?

    Et, en conséquence, il ne faut pas raccorder la première ligne en erreur avec la précédente, mais plutôt raccorder la deuxième ligne en erreur avec la précédente, non?

    Car si on met la première ligne en erreur à la suite de sa précédente, alors celle-ci fera plus de 600 caractères, non?

    PS: il est clair qu'il vaut mieux utiliser un bon script, mais je voudrais préciser que "emacs" est un éditeur assez efficace pour éditer à la main (ou avec des macros emacs) de tels gros fichiers...

  5. #5
    Membre confirmé Avatar de Bragu Demon
    Homme Profil pro
    Intégrateur d'Explopitation
    Inscrit en
    Juin 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Intégrateur d'Explopitation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2013
    Messages : 125
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Euh... c'est pas complètement clair pour moi...


    egrep -vn -C2 '^\w{3}\$*{596}' fichier # 2 lignes avant et 2 lignes après
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    1493889-SUC$C005$D$0001493888$S$30256402
    1493890-PDR$C005$D$0001493889$C$30256402
    1493891:                                
    1493892-TRA$C005$D$0001493890$C$30256402
    1493893-UGD$C005$D$0001493891$C$30256402
    Voici comment sont constituées les lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DEB$C005$E$2$    $    $0000000000$0999999999$ACTIVE $
    PDR$C005$D$0000000001$M$2014
    ...
    DET$C005$D$0005497216$C$72110
    FIN$C005$F$000000005497218$
    colonnes 1 à 3 : identification du type d'enregistrement (DEB -> Début, FIN -> Fin)
    colonnes 5 à 8 : code institutionnel
    colonnes 10 : type d'information (E -> Entête, D -> Data, F -> Fin)
    colonnes 12 -> "$" : numéro d'enregistrement
    chaque enregistrement fait 600 caractères de long, et donc 600 octets de long (c'est extrait d'un DB2 Z/OS)

    On voit ici que le 4ème champ (et pas le 5ème comme je le disais plus haut) contient le numéro de l'enregistrement.
    La ligne 1493889 est parfaite. On observe un décalage dans la numérotation, dû au fait que la 1ère ligne (DEB$) n'est pas numérotée.
    La ligne de fin (FIN$) contient elle le nombre de ligne dans le fichier (ligne DEB$ comprise).
    Ainsi wc -l fichier retourne 5497219 alors que la bannière de fin (FIN$) dit que l'on doit en avoir 54972198.




    nature des fins de ligne (j'ai triché j'ai mis qu'une ligne avant et après) :
    egrep -vn -C1 '^\w{3}\$*{596}' fichier | od -c
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    0000000   1   4   9   3   8   9   0   -   P   D   R   $   C   0   0   5
    0000020   $   D   $   0   0   0   1   4   9   3   8   8   9   $   C   $
    0000040   3   0   2   5   6   4   0   2   5
    0000060                   $   0   3   0   2   5   6   4   0   2   5   $
    0000100   0   1   0   1   0   8   1   6   4   8   $   0   0   0   0   0
    0000120   0   0   0   0   0   $   0   0   0   0   0   0   2   6   1   2
    0000140   6   7   0   5   4   $   0   0   6   6   3   6   3   4   7   4
    0000160   $   0   0   0   0   0   $   0   0   0   0   0   0   0   0   0
    0000200   0   0   0   0   0   0   $   0   0   0   0   0   0   0   0   0
    *
    0000240   0   0   0   0   0   0   $   0   0   0   $   0   0   0   $   0
    0000260   0   0   $   0   0   0   $   0   0   0   0   0   $
    0000300                               $
    0000320                                                   $
    0000340       $   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0000360   $
    0000400
    *
    0000440                                                       $       $
    0000460
    0000500   $   2   0   0   1   -   0   2   -   1   2   $   2   0   1   3
    0000520   -   0   3   -   0   1   $   0   9   6   $   0   1   $   2   0
    0000540   0   $   N   $   0   0   0   0   0   0   0   0   0   3   $   2
    0000560   0   1   1   -   1   1   -   0   1   $   2   0   1   6   -   1
    0000600   2   -   0   1   $   M   I   G   R   A   T   I   O   N
    0000620                                       $   P   N   D   S   M   B
    0000640   P   1                                                   $
    0000660       $   C   L   I   N   I   Q   U   E       S   A   I   N   T
    0000700   -   S   A   U   V   E   U   R      \n   1   4   9   3   8   9
    0000720   1   :
    0000740
    *
    0001020                                                           $   S
    0001040   I   R   N   $   4   1   3   9   6   8   4   1   3
    0001060                                   $
    0001100
    *
    0001140                                  \n   1   4   9   3   8   9   2
    0001160   -   T   R   A   $   C   0   0   5   $   D   $   0   0   0   1
    0001200   4   9   3   8   9   0   $   C   $   3   0   2   5   6   4   0
    0001220   2   5                                               $   0   3
    0001240   0   2   5   6   4   0   2   5   $   0   1   0   1   0   8   1
    0001260   6   4   8   $   0   0   0   0   0   0   0   0   0   0   $   0
    0001300   0   0   0   0   0   2   6   1   2   6   7   0   5   4   $   0
    0001320   0   6   6   3   6   3   4   7   4   $   0   0   0   0   5   $
    0001340   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   $
    *
    0001420   0   0   4   $   0   0   1   $   0   0   0   $   0   0   0   $
    0001440   0   0   0   0   0   $
    0001460   $
    0001500                       $                   $   0   0   0   0   0
    0001520   0   0   0   0   0   0   0   0   0   $   C   $   0   1   3   $
    0001540   C   $   0   1   3   $               $               $   0   0
    0001560   0   3   0   3   7   3   6   6   $   0   0   4   $   0   1   6
    0001600   2   4   0   0   $   0   0   0   0   0   0   0   $   0   1   6
    0001620   2   4   0   0   $   0   0   0   0   0   0   0   $   2   0   1
    0001640   6   -   1   2   -   0   1   $
    0001660           $   P   N   D   S   M   B   P   1
    0001700                               $
    0001720                                                   $
    0001740
    *
    0002300                                      \n
    0002312


    Citation Envoyé par jack-ft Voir le message
    D'après ce que tu dis, j'ai l'impression que certaines lignes sont "coupées", avec un CR ou un LF en trop, et qu'il faut raccorder les bouts.

    Mais, si c'est bien ça, alors tu devrais avoir DEUX lignes consécutives avec moins de 600 caractères, non?
    C'est presque vrai, dans mes contrôles je dois m'assurer que chaque commence par 3 lettres + "$" ET soit de 600 de long, d'ou mon egrep :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    egrep -vn '^\w{3}\$*{596}'  fichier
    le -v permet de récupérer ce qui NE CORRESPOND PAS à l'expression qui suis, et le -n pour récupérer le numéro de la ligne.
    Dans ce cas là, il faut bien recoller la ligne récupérée avec la précédente.

    Par contre avec un test sur uniquement la longueur de la ligne il faut recoller les 2 lignes en erreurs, la deuxième ligne en erreur avec la précédente, comme tu le dis.
    Cette commande ne fonctionne pas, elle ne me rencoi rien du tout à la console ... :-(
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    egrep -vn '^*{600}' fichier
    Citation Envoyé par jack-ft Voir le message
    PS: il est clair qu'il vaut mieux utiliser un bon script, mais je voudrais préciser que "emacs" est un éditeur assez efficace pour éditer à la main (ou avec des macros emacs) de tels gros fichiers...
    J'ai bien l'intention de mettre tout ça dans un script.
    Concernant emacs, je ne connais mais que de nom et je suis parfaitement incapable d'en faire quoique se soit ( pour l'instant :-) )

    Actuellement :
    Je sais identifier les lignes que je doit concaténer
    Je sais concaténer les 2 lignes qui m'intéresse

    A faire :
    concaténer mon fichier avec ma ligne réparée (la mettre bêtement à la fin) --> CAT va m'aider
    Supprimer les lignes utilisées pour effectuer la réparation --> sed -e '${ligne_precedente}d;${ligne_en_erreur}d' fichier
    Faire un sort croissant sur le champ 4 du fichier (dont le séparateur est le $ )

  6. #6
    Membre confirmé Avatar de Bragu Demon
    Homme Profil pro
    Intégrateur d'Explopitation
    Inscrit en
    Juin 2013
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Intégrateur d'Explopitation
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2013
    Messages : 125
    Par défaut
    Actuellement :



    Il ne me manque "que" :
    Faire un sort croissant sur le champ 4 du fichier (dont le séparateur est le $ ) :
    [EDIT]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat fichier | sort -t$ -k 4n,4n > NEW_fichier
    [/EDIT]

    Je vous tiens au courant ^^

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 103
    Par défaut
    Citation Envoyé par Bragu Demon Voir le message
    C'est presque vrai, dans mes contrôles je dois m'assurer que chaque commence par 3 lettres + "$" ET soit de 600 de long, d'ou mon egrep :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    egrep -vn '^\w{3}\$*{596}'  fichier
    Supposons que ce soit egrep -vn '^\w{3}\$.{596}' fichier comme corrigé par disedorgue...


    le -v permet de récupérer ce qui NE CORRESPOND PAS à l'expression qui suis, et le -n pour récupérer le numéro de la ligne.
    oui, je connais un peu "grep"...

    Dans ce cas là, il faut bien recoller la ligne récupérée avec la précédente.
    Oui, mais là, non... ou alors je persiste à ne pas comprendre!

    Tu décèles la première ligne mauvaise. Elle est consécutive à une précédente qui est forcément bonne, puisque la première mauvaise est, comment dire, la première à être mauvaise...

    Du coup, si tu colles la mauvaise ligne à la fin de la précédente, celle-ci verra sa longueur augmenter et ne sera plus bonne, non?

    Par contre avec un test sur uniquement la longueur de la ligne il faut recoller les 2 lignes en erreurs, la deuxième ligne en erreur avec la précédente, comme tu le dis.
    Hum...

    Cette commande ne fonctionne pas, elle ne me rencoi rien du tout à la console ... :-(
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    egrep -vn '^*{600}' fichier
    Normal... (voir disedorgue)

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

Discussions similaires

  1. Transfert de fichiers volumineux par le net
    Par K-Kaï dans le forum Général Conception Web
    Réponses: 8
    Dernier message: 14/07/2008, 13h15
  2. [FTP] Editer des fichiers distants
    Par bigtof dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 17/08/2006, 00h28
  3. XP PRO SP2 detection de fichiers volumineux
    Par HOFER dans le forum Windows XP
    Réponses: 3
    Dernier message: 14/08/2006, 12h47
  4. [XML-JSP] Editer un fichier XML
    Par sempire dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 24/08/2005, 22h24
  5. Chargement fichier volumineux
    Par kirsoul dans le forum Installation
    Réponses: 2
    Dernier message: 26/07/2005, 14h53

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