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 :

transpose en colonne deux par deux et output le resultat dans un fichier


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 45
    Par défaut transpose en colonne deux par deux et output le resultat dans un fichier
    Bonjour,

    Voici le format de mon fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    "1.1,2,3,4,5,64,3,9",,,,,1,aine
    "2,3,4,5.4",,,,,3,bb
    "3,4.3,5,6,6,2",,,,,2,ff
    et j'aimerais pour chaque lignes transpose en colonne deux par deux les valeurs stocker entre "" dans un fichier dont le nom du fichier correspond par exemple pour la 1er ligne 1aine.

    par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ls
    1aine 3bb 2ff
    $cat 1aine
    1.1 2
    3 4
    5 64
    3 9
    Voici mon premier code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/bash
    while IFS= read -r line; do
        echo  $line | cut -d'"' -f2 > temp
        cat temp
        name=$(cut -d'"' -s -f3 (echo $line) | sed 's/,/ /g' | sed 's/ //g')
        echo $name
        awk -F, '{for(i=1;i<=NF;i++)printf "%s%s",$i,(i%2&&i!=NF?OFS:ORS)}' temp > $name
    done < "$1"
    Mais j'obtiens ceci en erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    1.1,2,3,4,5,64,3,9
    ./code: command substitution: ligne 6: erreur de syntaxe près du symbole inattendu « ( »
    ./code: command substitution: ligne 6: `cut -d'"' -s -f3 (echo $line) | sed 's/,/ /g' | sed 's/ //g')'
    Je ne suis pas un champion en shell, c'est toujours pour moi un peu obscure.
    Je vous en remercie
    Votre plus grand admirateur

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    Bonjour,

    tu n'as aucun contrôle sur la génération du fichier pour améliorer son format ! ?

    les champs intermédiaires ne sont pas toujours vides ?!

    je ne traiterais pas ça en shell. j'utiliserais directement awk...
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Oui, à défaut d'avoir quelque chose d'approprié pour lire un fichier csv (sans devoir utiliser un module Python ou Perl, ou encore un couteau suisse de derrière les fagots comme Miller qu'on installe puis qu'on oublie aussitôt):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F\" '{while (index($2,",")) { sub(",", " ", $2); sub(",", "\n", $2) }; gsub(",", "", $3); printf("%s",$2)>$3}' file
    C'est quand même dingue, qu'il n'y ait pas un petit utilitaire csv de trois lettres sans deux tonnes de python cachées derrière pour faire ça (histoire de pas avoir à se tartiner la gestions des séparateurs protégés).

    Sinon je pense, sans être expert en bash, qu'il ne s'attend pas à un sous-shell à cet endroit là, par contre, si tu fais un redirection, ça devrait marcher:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cut -d'"' -s -f3 <(echo $line)
    ou plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cut -d'"' -s -f3 <<<"$line"

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    j'envisageais des split() sur les deux champs (séparés par un ")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F '"' '{nbCont=split($2,contenu,",") ; for(i=1;i<=nbCont;i++){ printf("%s ", contenu[i]); if(i%2)print ""}}' fichier.csv
    il faut améliorer la sortie : il y a un espace en trop en fin de ligne.

    la constitution du nom du fichier cible est trivial.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    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 349
    Par défaut
    Ou juste en (gnu) sed:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -Ez 's/"([^"]*)"[^\n]*\n/\1,/g;s/([^,]*,[^,]*),/\1\n/g;s/,/ /g' fichier

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 45
    Par défaut
    Mon code update ;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/bash
    while IFS= read -r line; do
        echo  $line | cut -d'"' -f2 > temp
        cat temp
        name=$(cut -d'"' -s -f3 <<<"$line" | sed 's/,/ /g' | sed 's/ //g')
        echo $name
        touch $name
        awk -F, '{for(i=1;i<=NF;i++)printf "%s%s",$i,(i%2&&i!=NF?OFS:ORS)}' temp > $name
    done < "$1"
    Resultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    1.1,2,3,4,5,64,3,9
    1aine
    2,3,4,5.4
    3bb
    3,4.3,5,6,6,2
    2ff
    J'ai bien mes fichiers de sortie avec les bons noms de fichiers et les bonnes valeurs.
    Merci !

    Sinon concernant plusieurs de vos commandes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    awk -F\" '{while (index($2,",")) { sub(",", " ", $2); sub(",", "\n", $2) }; gsub(",", "", $3); printf("%s",$2)>$3}' aa > alors
    awk: ligne de commande:1: (FILENAME=aa FNR=4) fatal*: l'expression dans la redirection «*>*» donne une chaîne n
    ulle


    cette commande marche presque mais ne comprends pas les floats :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    awk -F '"' '{nbCont=split($2,contenu,",") ; for(i=1;i<=nbCont;i++){ printf("%s ", contenu[i]); if(i%2)print ""}}' aa
    1.1 
    2 3 
    4 5 
    64 3 
    9 2 
    3 4 
    5.4 3 
    4.3 5 
    6 6 
    2
    et la derniere elle fonctionne bien :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sed -Ez 's/"([^"]*)"[^\n]*\n/\1,/g;s/([^,]*,[^,]*),/\1\n/g;s/,/ /g' aa
    1.1 2
    3 4
    5 64
    3 9
    2 3
    4 5.4
    3 4.3
    5 6
    6 2

  7. #7
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    je soupçonne une différence de format entre l'exemple donné et le fichier traité sur ta machine.

    EDIT : ou la version de awk...


    ce n'est pas un problème de float, c'est moi qui ait interverti la condition : if (i%2 == 0) print ""
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    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 349
    Par défaut
    Citation Envoyé par Suntory Voir le message
    Sinon concernant plusieurs de vos commandes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    awk -F\" '{while (index($2,",")) { sub(",", " ", $2); sub(",", "\n", $2) }; gsub(",", "", $3); printf("%s",$2)>$3}' aa > alors
    awk: ligne de commande:1: (FILENAME=aa FNR=4) fatal*: l'expression dans la redirection «*>*» donne une chaîne n
    ulle
    La blague: cette ligne de awk fait tout le boulot de ton script, si tu la lançais comme indiqué par son créateur...(sans redirection)

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

Discussions similaires

  1. [XL-365] Selectionner deux plages et les assembler dans un fichier Word
    Par thesus_size dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 24/12/2019, 17h22
  2. [PowerShell] Comment supprimer deux 0 sur plusieurs lignes dans un fichier txt
    Par Martinez Albatros dans le forum Scripts/Batch
    Réponses: 7
    Dernier message: 01/08/2019, 13h54
  3. Réponses: 2
    Dernier message: 10/10/2018, 14h52
  4. Trouver les deux points les plus éloignés dans un fichier .stp/.step (ISO-10303-21)
    Par delta07 dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 03/04/2017, 17h08
  5. Réponses: 3
    Dernier message: 01/02/2016, 10h59

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