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

Scripts/Batch Discussion :

Manipulation d'un fichier texte, variables et SQL


Sujet :

Scripts/Batch

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Septembre 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2014
    Messages : 22
    Par défaut Manipulation d'un fichier texte, variables et SQL
    Bonjour à vous le forum,

    Aussi nouveau que je sois ici, je le suis autant sur PS.
    C'est pourquoi je sollicite votre aide sur ma situation.

    J'ai un fichier texte assez conséquent (environ 400 blocs) qui se trouve sous la forme suivante, je me suis limité à 2 exemples :

    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
    [10]
    nom=mon_nom
    prenom=mon_prenom
    code=1111
    adresse=mon_adresse
    postal=12345
    sexe=m
    tel=1234567890
    
    [12]
    nom=mon_nom1
    prenom=mon_prenom1
    code=2222
    adresse=mon_adresse1
    postal=12345
    sexe=f
    tel=1234567891
    Ce que je souhaite faire, c'est de pouvoir récupérer juste les valeurs de la façon suivante :

    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
    10
    mon_nom
    mon_prenom
    1111
    mon_adresse
    12345
    m
    1234567890
    
    12
    mon_nom1
    mon_prenom2
    2222
    mon_adresse2
    12345
    f
    1234567891
    Pour ensuite les mettre dans une requête SQL qui va insérer les données dans une base.

    Dans un premier temps, ma question est de savoir comment récupérer juste ces valeurs et les insérer chacune dans une variable.
    En espérant que ma demande soit assez précise.

    Merci de votre aide.

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Salut,
    Citation Envoyé par lacava Voir le message
    Bonjour à vous le forum,
    J'ai un fichier texte assez conséquent (environ 400 blocs) qui se trouve sous la forme suivante, je me suis limité à 2 exemples :
    Pour analyser ce type de fichier structuré il faut en connaitre toutes les règles. Nb de lignes par bloc, structure de chaque ligne
    Ensuite la création d'objet ou d'une ligne de requête sera plus aisé.

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Septembre 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2014
    Messages : 22
    Par défaut Manipulation d'un fichier texte, variables et SQL
    Bonjour Laurent,

    Merci bien de votre retour.

    Pour analyser ce type de fichier structuré il faut en connaitre toutes les règles. Nb de lignes par bloc, structure de chaque ligne
    Ensuite la création d'objet ou d'une ligne de requête sera plus aisé.
    Pour ce qui est des règles, pour les 2 exemples que j'ai illustré, tous les autres sont fait de la même façon donc cette structure reste la même qui soit pour le [21], le [112], le [203] et ainsi de suite.
    Par contre, je n'ai pas mentionné que dans certains paramètres, se trouve un caractère spécial, exemple du [20] :

    [20]
    ...
    etage=1/2
    dpt=bloc <30>

    ...

    Et pour certains paramètres, le nombre de caractères sur la ligne peut changer (ex : etage=1/21).
    Donc concrètement, si l'on compte ce paramètre entre [] avec les autres valeurs qui lui sont attribuées, cela fait 20 lignes exactement par bloc.
    Par inattention, j'ai mis 10 et 20 comme valeur entre crochet mais en fait j'ai 4 chiffres et ça pour tout le monde. Je le précise au cas où cela aurait son importance.
    J'espère répondre à toutes vos questions.

    Merci.

  4. #4
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Comme c'est le type de traitement qu'on peut réutiliser, voici une ébauche :
    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    $file ='c:\temp\datas.txt'
    @'
    [10]
    nom=mon_nom
    prenom=mon_prenom
    code=1111
    adresse=mon_adresse
    postal=12345
    sexe=m
    tel=1234567890
    etage=1/2
    dpt=bloc <30>
    
    [12]
    nom=mon_nom1
    prenom=mon_prenom1
    code=2222
    adresse=mon_adresse1
    postal=12345
    sexe=f
    tel=1234567891
    etage=1/2
    dpt=bloc <30>
    
    [12]
    nom=mon_nom1
    prenom=mon_prenom1
    code=2222
    adresse=mon_adresse1
    postal=12345
    sexe=f
    tel=1234567891
    '@ > $File
    
    Function Split-Bloc {
      $NombreDeLigneParBloc=11
      $NombreDePropriétés=10
    
      $Elements=Get-Content $File -ReadCount $NombreDeLigneParBloc
      
       #tableau de tableau
      Foreach( $Lignes in $Elements)
      {
           #Transforme un bloc en un objet Powershell 
          $CurrentObject= New-Object PSObject         
          
           #Ligne d'un bloc
           Foreach( $Ligne in $Lignes)
           {
            #Write-debug "Traite la ligne : $Ligne"
             switch -regex ($Ligne) 
             {
                 #séparateur + valeur sur quatre chiffres + séparateur
                '^\[(?<Number>\d{1,4})\]$'     { 
                                                  Write-debug ("`tAjoute la propriété {0}"-F $Matches.0)
                                                  $CurrentObject.psObject.Properties.Add( 
                                                    (New-Object Management.Automation.PSNoteProperty('Number',$Matches.Number)))
                                                  Continue 
                                               }
                    
                 #Nom + séparateur + valeur
                '^(?<Name>.*?)=(?<Value>.*)$' { 
                                                Write-debug ("`tAjoute la propriété {0}"-F $Matches.0)
                                                $CurrentObject.psObject.Properties.Add(
                                                  (New-Object Management.Automation.PSNoteProperty($Matches.Name, $Matches.Value)))
                                                Continue 
                                              }
      
                ''                            { Write-Debug "`tLigne vide";Continue }
                default {Write-Error 'Cas inconnu : $Element' }
             }
           } #lignes
           
           #Todo liste des noms de propriété, car ETS peut ajouter des membres 
          $nbProperties=0;$CurrentObject.psobject.Properties.GetEnumerator()|% {$nbProperties++}
          Write-Debug "nbProperties=$nbProperties" 
          if ($nbProperties -ne $NombreDePropriétés) 
          { Write-Error "Object incomplet :  $CurrentObject" }
          #Controles d'autres régles, possible...
            
          Write-Output $CurrentObject 
      }#Elements
    } #Split-Bloc
    
    $Objets=Split-Bloc
    
    $Objets.Count
    Citation Envoyé par lacava Voir le message
    Et pour certains paramètres, le nombre de caractères sur la ligne peut changer (ex : etage=1/21).
    L'autre étape serait d'insérer des règles de validation sur les données de l'objet, à moins qu'une procédure stockée s'en charge...
    Citation Envoyé par lacava Voir le message
    Je le précise au cas où cela aurait son importance.
    C'est toi seul qui juge si cela l'est ou pas ! je ne connais pas le fonctionnel.
    J'ai préféré construire des objets ainsi tu peux filtrer la collection, ou regrouper des objets pour une insertion par lots, via BCP.exe par exemple.

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Septembre 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2014
    Messages : 22
    Par défaut
    J'ai dû modifier un peu votre code pour que cela fonctionne de mon côté. $Matches.0 devient $Matches
    De ce que je comprends, il arrive bien à lire les valeurs après le '=' de chaque ligne ainsi que le nombre entre [].
    Et ce qu'il fait, au final, il compte le nombre de blocs.

    Pour voir ce que la variable $Objets retourne, j'ai rajouté : Write-Output $Objets au code et j'enregistre dans un fichier
    $Objets=Split-Bloc > $files2.

    Il me retourne le résultat suivant :

    Number : 10
    nom : mon_nom
    prenom : mon_prenom
    code : 1111
    adresse : mon_adresse
    postal : 12345
    sexe : m
    tel : 1234567890
    etage : 1/2
    dpt : bloc <30>

    Number : 12
    nom : mon_nom1
    prenom : mon_prenom1
    code : 2222
    adresse : mon_adresse1
    postal : 12345
    sexe : f
    tel : 1234567891
    etage : 1/2
    dpt : bloc <30>


    Donc il arrive à bien séparer les blocs et à retourner les valeurs de chaque ligne sous une forme un peu plus normalisée.

    Avant d'utiliser BCP, j'ai essayé de retourner en résultat seulement le nombre et les valeurs après le ':' avec les variables $Matches.Number et $Matches.Value, qui je pense sont les variables où se stockent les fameuses valeurs, mais je n'y suis pas arrivé.

    Finalement la longueur peut varier, le script arrivera quand même à l'interpréter sans créer de règles ou autres.

    Du coup pour ce qui est de BCP, est-ce possible de le faire directement à partir du code, ou l'on doit partir d'un fichier non xml généré par le code ?

  6. #6
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lacava Voir le message
    Pour voir ce que la variable $Objets retourne, j'ai rajouté : Write-Output $Objets au code et j'enregistre dans un fichier
    Comme la fonction renvoie des objets tu peux ne pas utiliser de variable intermédiaire :
    Citation Envoyé par lacava Voir le message
    Avant d'utiliser BCP, j'ai essayé de retourner en résultat seulement le nombre et les valeurs après le ':' avec les variables $Matches.Number et $Matches.Value, qui je pense sont les variables où se stockent les fameuses valeurs, mais je n'y suis pas arrivé.
    C'est à dire construire une ligne d'insert SQL ?
    Citation Envoyé par lacava Voir le message
    Du coup pour ce qui est de BCP, est-ce possible de le faire directement à partir du code, ou l'on doit partir d'un fichier non xml généré par le code ?
    Je crois que BCP.exe nécessite un fichier intermédiaire, voici un exemple via un csv :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $csv="C:\Script\DATA\Tables\tablename.csv"
    bcp Base.dbo.TableName in $csv -q -c -t ';' -S My_MSSQLSERVER -U MyAccountName -P MyPassWord
    La contrainte est que la première ligne du fichier .csv ne doit pas contenir les noms des champs et les guillemets doivent être supprimé.
    Un exemple rapido :
    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
    function Skip-Count() {
    #jaredpar's WebLog
    # Skip the specified number of items
    #Example:
    #
    #1..10 | skip-count 5 #renvoi 6..10
    #Ignore un nombre spécifié d'éléments dans une séquence puis retourne les éléments restants. 
    
        param ( $count = $(throw "Need a count") )
        begin { 
            $i = 0
        }
        process {
            if ( $i -ge $count ) { 
                $_
            }
            $i += 1
        }
        end {}
    }
    
    Function ConvertTo-CsvNoQuote([string]$PathCsv)
    {
        #remplace les guillemets
      $T=Get-content $PathCsv|% { $_ -replace '"',""}
        #retire la première ligne contenant les noms des champs
      $T|Skip-Count 1|Set-content $PathCsv
    }
    $csvFileName="C:\Script\DATA\Tables\tablename.csv"
    Split-Bloc|Export-csv $csvFileName -notype -Delimiter ';'
    ConvertTo-CsvNoQuote  "$csvFileName.New" # a revoir
    
    bcp Base.dbo.TableName in $"$csvFileName.New" -q -c -t ';' -S My_MSSQLSERVER -U MyAccountName -P MyPassWord
    Je ne me souviens plus comment bcp traite les lignes en erreur et peut être que cet BCP.exe sait manipuler des blocs, à vérifier dans la doc.
    Il y a également SMO (BulkLoad), mais il faut 'recoder' une partie de BCP.
    Cette approche date de 4-5 ans, il existe peut être mieux depuis.

Discussions similaires

  1. Réponses: 0
    Dernier message: 11/02/2008, 11h37
  2. Réponses: 6
    Dernier message: 14/03/2007, 14h36
  3. [BATCH] Manipulation dans un fichier texte
    Par Bloodscalp dans le forum Windows
    Réponses: 2
    Dernier message: 13/09/2006, 15h49
  4. Réponses: 13
    Dernier message: 05/07/2006, 09h39
  5. Réponses: 2
    Dernier message: 16/12/2004, 15h33

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