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 :

Extraire des fichiers XML et PDF d'un fichier les compilant (utilisation de "tr")


Sujet :

Shell et commandes GNU

  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut Extraire des fichiers XML et PDF d'un fichier les compilant (utilisation de "tr")
    Bonjour,

    j'ai un fichier test.bin qui est une compilation de fichiers XML et PDF et je dois les séparer. Exemple de début de fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="UTF-8"?>
    <infos>
    Courriers administratifs dematerialises
    </infos>%PDF-1.5
    %M-5M-5M-5M-5
    1 0 obj
    ...
    La commande "awk '/%PDF/{c++} {print > FILENAME"_"c }' /tmp/test.bin" permet de séparer comme en fonction de la ligne qui contient "%PDF" mais comme il y a d'autres données avant "%PDF" ça ne fonctionne pas. J'ai essayé de transformé au préalable "</infos>%PDF-1.5" par "</infos>\n%PDF-1.5" mais je n'y arrive pas (avec la commande : tr '%PDF' '\n%PDF' < test.bin > test2.bin) mais ça donne des choses imprévues : le "F" de "%PDF" a disparu, ainsi que le "%" de "%M" et une ligne blanche est ajoutée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?xml version="1.0" encoding="UTD-8"?>
    <infos>
    Courriers administratifs dematerialises
    </infos>
    %PD-1.5
     
    M-5M-5M-5M-5
    1 0 obj
    ...
    Christophe

    Pensez à mettre quand c'est le cas.

  2. #2
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '/%PDF/{$0=gensub(/.*(%PDF.*)/,"\\1","1",$0); c++} {print > FILENAME"_"c; }' fichier
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    Merci pour la réponse mais j'ai l'erreur suivante : awk: Function gensub is not defined.

    J'ai une autre piste la commande "dd skip=1 count=98 if=/tmp/test.bin of=/tmp/test1.bin bs=1" permet de découper précisément (de 1 à 98 ici). Je peux donc l'utiliser dans un script, malheureusement je n'arrive pas à trouver de commande me donnant les positions d'une chaîne de caractères dans un fichier.
    Christophe

    Pensez à mettre quand c'est le cas.

  4. #4
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    C'est un problème de version de awk.

    Same player shoot again.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '/%PDF/{sub(/.*%PDF/,"%PDF",$0); c++} {print > FILENAME"_"c; }'
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    La nouvelle commande passe mais elle fait disparaitre ce qu'il y a devant le "%PDF".
    Premier fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <?xml version="1.0" encoding="UTF-8"?>
    <infos>
    Courriers administratifs dematerialises
    Il manque "</infos>" à la fin.

    Deuxième fichier (OK) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    %PDF-1.5
    %M-5M-5M-5M-5
    1 0 obj
    ...
    La chaîne de caractères "</infos>" précédant "%PDF" a donc disparu.
    Christophe

    Pensez à mettre quand c'est le cas.

  6. #6
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Ben oui, évidemment. Tu peux sauver le début avec un substr() et un index().

    Sinon, autre idée : changer le séparateur d'enregistrement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'BEGIN{RS="%PDF";} {print ((NR>1)?"%PDF":"")$0 >FILENAME"_"NR}' fichier
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    La dernière commande génère 1311 fichiers au lieu de 6. Je vais chercher pour récupérer ce qui précède "%PDF".
    Christophe

    Pensez à mettre quand c'est le cas.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut dd + trouver position ?
    J'ai vraiment du mal avec awk. Et je ne suis pas sûr que awk puisse faire simplement ce que je veux (et que j'ai mal exprimé dans mon premier message).
    J'ai des fichiers concaténant plusieurs fichiers (XML et PDF, cf. couleurs ci-dessous) que je souhaite extraire :
    ---
    <?xml version="1.0" encoding="UTF-8"?>
    <infos>
    ...
    </infos>
    %PDF-1.5
    %M-5M-5M-5M-5
    1 0 obj
    ...
    79562
    %%EOF
    <?xml version="1.0" encoding="UTF-8"?>
    <infos>
    ...
    </infos>
    %PDF-1.5
    %µµµµ
    79046
    %%EOF

    ---
    La commande dd fait ce que je veux mais j'ai besoin de connaître la position de "%PDF" et "<?xml".
    Exemple avec dd permettant de récupérer les 4 fichiers ci-dessus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    dd skip=1 count=98 if=/tmp/test.bin of=/tmp/test_toc/fichiers/A123Abcd-1.xml bs=1
    dd skip=98 count=79740 if=/tmp/test.bin of=/tmp/test_toc/fichiers/A123Abcd-1.pdf bs=1
    dd skip=79838 count=98 if=/tmp/test.bin of=/tmp/test_toc/fichiers/A123Abcd-2.xml bs=1
    dd skip=79936 count=79740 if=/tmp/test.bin of=/tmp/test_toc/fichiers/A123Abcd-2.pdf bs=1
    J'ai trouvé une commande awk qui donne la ligne et la position sur la ligne mais j'ai besoin de la position dans le fichier. Comment puis-je avoir ces positions ?
    Christophe

    Pensez à mettre quand c'est le cas.

  9. #9
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    une solution gawk :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ awk 'BEGIN{RS=""} {split(gensub(/(<\/infos>|%%EOF)/, "\\1\n\n", "g", $0), tab, /\n\n/); for (i=1; i<length(tab); i++) {print tab[i] > "extract" i}}' fichier
    et son résultat :
    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
    $ ls
    extract1  extract2  extract3  extract4  fichier
     
    $ cat extract1
    <?xml version="1.0" encoding="UTF-8"?>
    <infos>
    ...
    </infos>
     
    $ cat extract2
    %PDF-1.5
    %M-5M-5M-5M-5
    1 0 obj
    ...
    79562
    %%EOF
     
    $ cat extract3
    <?xml version="1.0" encoding="UTF-8"?>
    <infos>
    ...
    </infos>
     
    $ cat extract4
    %PDF-1.5
    %µµµµ
    79046
    %%EOF

  10. #10
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    Merci. Ca a l'air de faire ce qu'il me faut. Par contre, quel shell / version faut-il pour avoir gensub ? J'ai le message d'erreur suivant :
    awk: Function gensub is not defined.
    Christophe

    Pensez à mettre quand c'est le cas.

  11. #11
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par Christophe P. Voir le message
    quel shell / version faut-il pour avoir gensub ?
    un shell Awk GNU (donc Linux), d'où le nom de GAwk

    l'avantage de gawk ici ce sont les backreferences qu'on utilise pour réécrire ce qu'on match (\1\n\n)

    on peut aussi vouloir envisager Perl ou Python et ainsi s'abstraire de la question GNU/pas GNU (c'est ce que je ferais) :
    Code PYTHON : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import sys, re
     
    with open(sys.argv[1], 'r') as f:
       data = f.read()
     
    for i,j in enumerate(re.findall(r'%PDF.+?%%EOF|<\?xml .+?</infos>', data, re.DOTALL)):
       with open('extract'+str(i+1), 'w') as f:
          f.write(j)

  12. #12
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    Je ne connais(sais) pas Python (seulement de nom). J'ai donc passé une bonne partie de la matinée sur https://docs.python.org/fr/3/tutorial/index.html. L'idée d'utiliser vraiment l'indentation est excellente, et il y a plein de bonnes idées dans ce langage.
    Le code fonctionne bien (et comme un changement d'OS est prévu sur le serveur, c'est parfait), cependant je me suis permis d'ajouter deux "closed" (j'ai bon ?).
    Merci.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import sys, re
     
    with open(sys.argv[1], 'r') as f:
       data = f.read()
    f.closed
     
    for i,j in enumerate(re.findall(r'%PDF.+?%%EOF|<\?xml .+?</infos>', data, re.DOTALL)):
       with open('extract'+str(i+1), 'w') as f:
          f.write(j)
    f.closed
    Christophe

    Pensez à mettre quand c'est le cas.

  13. #13
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    Après un test sur d'autres fichiers, je me suis apperçu que les fichiers XML commencent bien par "<?xml" mais ne finissent pas tous par "</infos>", mais sont tous avant un PDF. Voyez-vous une expression régulière qui permettrait de récupérer les données jusqu'avant "%PDF". Si ce n'est pas possible avec une expression régulière, je le ferai en deux passes et je supprimerai des fichiers fichiers XML le "%PDF" en trop.
    Christophe

    Pensez à mettre quand c'est le cas.

  14. #14
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par Christophe P. Voir le message
    je me suis permis d'ajouter deux "closed" (j'ai bon ?)
    en fait la fermeture du fichier est implicite avec la construction with open() à la fin du bloc le fichier est automatiquement fermé, pas besoin de le rajouter. (PEP 343)

    Citation Envoyé par Christophe P. Voir le message
    une expression régulière qui permettrait de récupérer les données jusqu'avant "%PDF"
    essaye voir en modifiant avec r'%PDF.+?%%EOF|<\?xml .+?(?:</infos>|(?=%PDF))'

  15. #15
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    Merci !
    Christophe

    Pensez à mettre quand c'est le cas.

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

Discussions similaires

  1. extraire des fichiers sons contenu dans un pdf
    Par pythéas dans le forum Documents
    Réponses: 1
    Dernier message: 16/05/2019, 10h25
  2. Extraire des données d'un Pdf en XML ?
    Par blackguitar dans le forum Format d'échange (XML, JSON...)
    Réponses: 8
    Dernier message: 21/08/2009, 11h58
  3. Extraire des fichiers vérolés
    Par koKoTis dans le forum Windows XP
    Réponses: 13
    Dernier message: 11/03/2007, 14h11
  4. Stocker / Extraire des fichiers dans une base Access
    Par bryan_fury75 dans le forum Bases de données
    Réponses: 5
    Dernier message: 14/06/2006, 15h17
  5. [xml] comment extraire des donnés xml
    Par Lodos dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 20/04/2006, 21h47

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