Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 03/06/2012, à 19:34

hugodu78

[shell] récupérer texte entre 2 balises [Résolu]

Bonjour tout le monde,

J'ai un fichier txt en entrée de la forme :

blablabla
<begin>
le texte 1 que je souhaite récupérer
<end>
blablabla
<begin>
le texte 2 que je souhaite récupérer
<end>
blablabla
.... 20 000 lignes et N <begin> <end>
 

Je souhaite récupérer <begin>texte 1<end> et le mettre dans un txt, <begin>texte 2<end> et le mettre dans un autre txt ...
Autant de txt que de <begin> <end>.

Comme je ne connais pas le shell j'ai recherché sur le net si je trouve mon bonheur mais malheureusement pas
à 100%.

J'ai trouvé la commande :

sed -n '/begin/,/end/p' fichierentrée.txt > fichiersortie.txt

Qui me récupère bien ce que je veux (<begin>texte 1<end><begin>texte 2<end>) mais problème
tout est dans le même fichier en sortie.

Avez vous des idées pour résoudre ce problème.
Merci d'avance pour votre aide

Dernière modification par hugodu78 (Le 04/06/2012, à 12:58)

Hors ligne

#2 Le 03/06/2012, à 20:35

dev/random

Re : [shell] récupérer texte entre 2 balises [Résolu]

Quelques lignes de awk:

awk '
/^<begin>/ { f=1; nf++; next }
/^<end>/ { f=0 }
{ if (f) print > "f-" nf; }
' < fichier_entree

..Les fichiers de sortie s'appelleront f-1, f-2.. dans le répertoire courant, mais c'est modifiable;
je sais pas ce que tu vas faire de ces 20.000 fichiers (mais ça me regarde pas !)


667, the neighbour of the beast..

Hors ligne

#3 Le 03/06/2012, à 20:42

pingouinux

Re : [shell] récupérer texte entre 2 balises [Résolu]

Bonsoir,
En python (génère out.1, out.2...) :

$ cat entre_balises.py
#! /usr/bin/python
# -*- coding: utf-8 -*-

import sys, re

rec_balises=re.compile('<begin>(.*?)<end>',re.M|re.S)
with open(sys.argv[1],'r') as f :
   ligs=f.read()
   n=0
   for k in rec_balises.findall(ligs) :
      n+=1
      with open('out.%d'%n,'w') as g : g.write( '%s\n'%(k) )

$ ./entre_balises.py fichier.txt

Dernière modification par pingouinux (Le 03/06/2012, à 20:42)

Hors ligne

#4 Le 03/06/2012, à 20:46

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Bonsoir dev/random,

Un énorme merci. Je vais tester ça et je te tiens au jus.
En fait mon fichier txt est un dsx (import de datastage.
Datastage est un ETL). Dans ce fichier des milliers de lignes
selon la taille des projets et des milliers de begin end car
ça correspond à un job. En fait tous les jobs sont dans le dsx et
mon équipe voulait faire un job par dsx.

Je ne sais pas si j'ai été clair smile en tout cas énorme merci.
bonne soirée

Hors ligne

#5 Le 03/06/2012, à 20:47

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Bonsoir pingouinux,

Merci beaucoup. Je vais également tester.
Bonne soirée

Hors ligne

#6 Le 04/06/2012, à 10:06

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Bonjour,

Merci beaucoup ça marche très bien. Maintenant à moi de me débrouiller pour récupérer l'entête du fichier d'entrée
pour le remettre aux fichiers de sortie. Et de récupérer le nom du job entre <begin> et <end> pour le mettre en nom
du fichier de sortie.

Merci à vous et bonne continuation

Hors ligne

#7 Le 04/06/2012, à 12:49

Hizoka

Re : [shell] récupérer texte entre 2 balises [Résolu]

t peux ajouter [resolu] dans ton titre de sujet alors smile


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#8 Le 04/06/2012, à 15:30

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Re,

Le code de dev/random me fait bien un txt en sortie avec chaque texte entre begin end.
Mais est ce que je peux garder le begin et end dans mon fichier de sortie. Il n'y a pas un -(quelque chose)
qui peut me faire ça ?

Merci d'avance

Hors ligne

#9 Le 04/06/2012, à 15:54

pingouinux

Re : [shell] récupérer texte entre 2 balises [Résolu]

Voilà :

$ cat entre_balises.py
#! /usr/bin/python
# -*- coding: utf-8 -*-

import sys, re

rec_balises=re.compile('(<begin>.*?<end>)',re.M|re.S)
with open(sys.argv[1],'r') as f :
   ligs=f.read()
   n=0
   for k in rec_balises.findall(ligs) :
      n+=1
      with open('out.%d'%n,'w') as g : g.write( '%s\n'%(k) )

Hors ligne

#10 Le 04/06/2012, à 16:25

dev/random

Re : [shell] récupérer texte entre 2 balises [Résolu]

hugodu78 a écrit :

Mais est ce que je peux garder le begin et end dans mon fichier de sortie. Il n'y a pas un -(quelque chose)
qui peut me faire ça ?

quelque chose, comme une modif, par ex ?..

awk '
/<begin>/ { f=1; nf++; }
/<end>/ { f=0; print > "f-" nf; }
{ if (f) print > "f-" nf; }
' < fichier_entree

667, the neighbour of the beast..

Hors ligne

#11 Le 04/06/2012, à 16:44

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Vous êtes trop trop fort. Cette fois ci plus dur. Transférer vos connaissances dans mon cerveau smile
un énorme merci à vous 2.

Voici mon code si quelqu'un à un jour le même problème (Attention ce n'est pas fini)

#! /usr/bin/sh

#--------------Se placer à la racine du serveur---------------#

cd /


#---------Script permettant de mettre un job par dsx----------#

#Liste des paramètres :
#1 - Nom du dsx global
#2 - Répertoire où se trouve le dsx global
#3 - Répertoire où placer les dsx par job


#-----------------Récupération des paramètres-----------------#

DsxGlobal=$1
RepDsxGlobal=$2
RepDsxJob=$3


#-----------------Test du nombre de paramètres----------------#

if [ $# -lt  3 ]
then
    echo "\n\n"
    echo "\t\t\t!!!!     ERREUR     !!!!\n"
    echo "Des paramètres nécessaires à l'exécution du script son manquants\n"
    echo "Rappel des paramètres :"
    echo "paramètre 1 : Nom du dsx global"
    echo "paramètre 2 : Répertoire où se trouve le dsx global"
    echo "paramètre 3 : Répertoire où placer les dsx par job"
    echo "\n\n"
    echo "\t\t\t!!!!SORTIE EN ERREUR!!!!"
    echo "\n\n"
    exit 1
fi

#---Se placer dans le répertoire où se trouve le dsx global---#

cd $2


#--------------Récupérer le header tu dsx global--------------#

header=`cat $1|sed -n '1,4p'`
echo "$header"

#le header sera mis dans les fichiers de sortie

awk '
/<begin dsjob>/ { f=1; nf++; }
/<end dsjob>/ { f=0; print > "f-"nf".txt"; }
{if (f) print > "f-"nf".txt"; }
' < $1

Hors ligne

#12 Le 04/06/2012, à 22:07

Totor

Re : [shell] récupérer texte entre 2 balises [Résolu]

je propose ceci :

awk -v RS="\n?<(begin|end) dsjob>\n?" '/.+/ { i++; printf "<begin dsjob>%s<end dsjob>\n", $0>"fichier"i".txt" }' ficher.txt

-- Lucid Lynx --

Hors ligne

#13 Le 05/06/2012, à 10:15

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Totor a écrit :

je propose ceci :

awk -v RS="\n?<(begin|end) dsjob>\n?" '/.+/ { i++; printf "<begin dsjob>%s<end dsjob>\n", $0>"fichier"i".txt" }' ficher.txt

Bonjour Totor,

Ton code fait un fichier de sortie par ligne. Moi je voulais récupérer seulement le texte entre les balises begin dsjob et end dsjob (pas le blablabla)
Mais merci beaucoup de ton aide

Hors ligne

#14 Le 05/06/2012, à 12:07

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

dev/random a écrit :
hugodu78 a écrit :

Mais est ce que je peux garder le begin et end dans mon fichier de sortie. Il n'y a pas un -(quelque chose)
qui peut me faire ça ?

quelque chose, comme une modif, par ex ?..

awk '
/<begin>/ { f=1; nf++; }
/<end>/ { f=0; print > "f-" nf; }
{ if (f) print > "f-" nf; }
' < fichier_entree

Dans le code ci dessus c'est à quel moment qu'il est écrit "<begin>texte" dans le fichier de sortie ?
Si je souhaite mettre le contenu d'une variable avant begin. Il n'y a pas moyen de faire

printf $toto && /<begin>/ { f=1; nf++; }

Merci.
Bonne journée

Hors ligne

#15 Le 05/06/2012, à 13:27

dev/random

Re : [shell] récupérer texte entre 2 balises [Résolu]

hugodu78 a écrit :

Dans le code ci dessus c'est à quel moment qu'il est écrit "<begin>texte" dans le fichier de sortie ?

J'ai oté l'instruction next, ce qui fait qu'il passe par if(f) print..


hugodu78 a écrit :

Si je souhaite mettre le contenu d'une variable avant begin. Il n'y a pas moyen de faire

printf $toto && /<begin>/ { f=1; nf++; }

awk ne mmarche pas comme ça (tu confonds pas avec perl ?!)
Bon, si tu exposais en entier ce que tu veux vraiment, plutôt que de rajouter des trucs au compte-goutte..


667, the neighbour of the beast..

Hors ligne

#16 Le 05/06/2012, à 14:00

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Bonjour dev/random

Donc j'explique ce que je veux faire de A à Z. J'ai un fichier dsx (marche comme un .txt).
Ce .dsx est un export d'un projet Datastage. Le fichier est de la forme :

header (6 lignes)
blablabla
<begin>
Identifier "nom job"
Date ""
....
<end>
blablabla
<begin>
Identifier "nom job"
Date ""
....
<end>
blablabla
.... 20 000 lignes et N <begin> <end>

Ce fichier contient donc tous les jobs du projet Datastage.
En fait je veux 1 job par dsx. (Code que tu m'as déjà donné).
Mais afin que le code marche il faut rajouter le header à chaque fichier.

C'est pour ça que j'ai fait :

header=`cat $1|sed -n '&,6p'`

Et je voulais l'ajouter à ton awk.
Ensuite ce qui serait beau est de prendre le nom du job pour le mettre en nom du fichier sortant
mais je crois que je vais oublier vu que je ne comprends rien à ce langage.

Voilà tu sais tout. Mais ne va pas te casser la tête car je suppose que tu as d'autres choses à faire et
tu as déjà été très sympa avec moi.

Hors ligne

#17 Le 05/06/2012, à 14:27

miniSeb

Re : [shell] récupérer texte entre 2 balises [Résolu]

Avec

head -6

ça ne te va pas ?

Hors ligne

#18 Le 05/06/2012, à 14:45

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Bonjour miniSeb,

J'arrive à récupérer le header du dsx global (celui qui contient tous les jobs) avec cette commande :

header=`cat $1|sed -n '&,6p'`

Mais après je voulais ajouter ce code aux fichiers de sortie (f-1.txt, f-2.txt ..)
et c'est la le problème smile Mais je vais quand même remplacer mon car|sed
par ta commande pour avoir un code plus propre.

Merci beaucoup

Hors ligne

#19 Le 05/06/2012, à 15:13

pingouinux

Re : [shell] récupérer texte entre 2 balises [Résolu]

Salut,

$ cat fichier.txt
header 1
header 2
header 3
header 4
header 5
header 6
blablabla
<begin>
Identifier "nom job1"
le texte 1 que je souhaite récupérer
suite texte 1 que je souhaite récupérer
<end>
blablabla
<begin>
Identifier "nom job2"
le texte 2 que je souhaite récupérer
suite texte 2 que je souhaite récupérer
<end>
blablabla
$ cat entre_balises.py
#! /usr/bin/python
# -*- coding: utf-8 -*-

import sys, re

rec_header=re.compile('(.*?\n){6}',re.M)
rec_balises=re.compile('(<begin>.*?<end>)',re.M|re.S)
rec_ident=re.compile('^Identifier\s+"?(.*?)"?$',re.M)
with open(sys.argv[1],'r') as f :
   ligs=f.read()
   k=rec_header.match(ligs)
   if k : header=k.group(0)
   n=0
   for k in rec_balises.findall(ligs) :
      n+=1
      k_nom=rec_ident.search(k)
      if k_nom : nom=k_nom.group(1)
      with open('%s'%nom,'w') as f : f.write( '%s%s\n'%(header,k) )
$ ./entre_balises.py fichier.txt
$ cat "nom job1"
header 1
header 2
header 3
header 4
header 5
header 6
<begin>
Identifier "nom job1"
le texte 1 que je souhaite récupérer
suite texte 1 que je souhaite récupérer
<end>
$ cat "nom job2"
header 1
header 2
header 3
header 4
header 5
header 6
<begin>
Identifier "nom job2"
le texte 2 que je souhaite récupérer
suite texte 2 que je souhaite récupérer
<end>

Dernière modification par pingouinux (Le 05/06/2012, à 15:20)

Hors ligne

#20 Le 05/06/2012, à 15:32

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

merciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii pingouinux

Hors ligne

#21 Le 05/06/2012, à 16:31

dev/random

Re : [shell] récupérer texte entre 2 balises [Résolu]

awk '
/^<begin>/ { f=1; next }      
/^Identifier/ { nom=$2 " " $3; 
                file="(head -6 fichier.txt;cat) > " nom;
                print "<begin>" | file;
              } 
/^<end>/ { f=0; print | file } 
{ if (f) print | file }
' < fichier.txt

Voilà.. Mais c'est pas le top au niveau performance, sur 20.000 fichiers ça va se sentir..


667, the neighbour of the beast..

Hors ligne

#22 Le 05/06/2012, à 16:42

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

merciiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii dev/random
Concernant les problèmes de performance je vais faire des tests. Mais moi je suis obligé de faire un job un dsx
donc les responsables du serveur vont se débrouiller pour les performances smile

En tout cas un énorme merci à toutes les personnes qui m'ont aidé.
[Résolu]

Hors ligne

#23 Le 06/06/2012, à 00:26

Postmortem

Re : [shell] récupérer texte entre 2 balises [Résolu]

Salut,
Une autre proposition en awk en partant de celui de Totor :

awk 'BEGIN { FS=OFS="\n"; RS="\n?<(begin|end)>\n?" }
    NR == 1 { HEADER_JOB=$1; for(i=2; i<=6; i++) HEADER_JOB=HEADER_JOB OFS $i }
    $1 ~ /Identifier "[^"]+"/ { split($1,NOM_JOB,/"/)
        print HEADER_JOB, "<begin>", $0, "<end>" > "/tmp/"NOM_JOB[2]".dsx" }' test.dsx

Dernière modification par Postmortem (Le 06/06/2012, à 00:30)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#24 Le 06/06/2012, à 11:03

hugodu78

Re : [shell] récupérer texte entre 2 balises [Résolu]

Bonjour Postmortem,

Merci beaucoup wink

Hors ligne

#25 Le 07/06/2012, à 10:23

106643

Re : [shell] récupérer texte entre 2 balises [Résolu]

dev/random a écrit :
awk '
/^<begin>/ { f=1; next }      
/^Identifier/ { nom=$2 " " $3; 
                file="(head -6 fichier.txt;cat) > " nom;
                print "<begin>" | file;
              } 
/^<end>/ { f=0; print | file } 
{ if (f) print | file }
' < fichier.txt

Hello
Je viens de tomber sur ce post en cherchant sur google. Moi j'ai presque le meme problème. J'ai changé fichier.txt par lenomdemonfichierd'entree.txt, changé identifier par name, changé head -6 par 2, ... que des petites modifications.
Ca me fait trop de fichiers par rapport à ce que je dois avoir. J'ai regardé mon fichier d'entrée et en fait il y a plusieurs name entre <begin> et <end> .  J'ai voulu remplacer cette ligne  /^Identifier/ { nom=$2 " " $3; par -->  /^<begin>\n Identifier/ { nom=$2 " " $3;   (car moi c'est le 1er name qui m’intéresse et sur la ligne au dessus il y a toujours <begin> contrairement aux autres name qui n'ont pas <begin> sur la ligne d'avant) .
second problème c'est quand je clic sur les fichiers de sorties l'ordinateur me demande choisir un programme sur le net ou sur votre ordinateur pour ouvrir votre fichier.
C'est normal ?
Merci d'avance pour vos réponses

106643

Hors ligne