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 :

Couper lignes de mauvaises longueurs et les coller dans un autre fichier


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Avril 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Avril 2016
    Messages : 3
    Par défaut Couper lignes de mauvaises longueurs et les coller dans un autre fichier
    Bonjour à tous,

    Voici mon objectif : J'ai un fichier texte brut. Je dois insérer un séparateur (pipe) à intervalles réguliers avec gestion des erreurs (avec un compte rendu).

    J'ai donc essayé le fonctionnement suivant :
    • décompte des lignes du fichier d'origine,
    • décompte des caractères par ligne :
      • si le nombre de caractères n'est pas celui attendu on enlève la ligne du fichier et on la colle dans le fichier "analyse" avec son numéro de ligne
      • si le nombre de caractères est correcte, on insert les séparateurs
    • Nouveau décompte de ligne et comparaison avec le premier pour connaitre le nombre d'erreurs


    L'insertion des pipes fonctionnent bien ainsi que le décompte des lignes.

    Le problème que je n'arrive pas à résoudre c'est de couper les lignes défectueuses et les insérer dans un autre fichier (mon code ne fonctionne absolument pas pour cette partie).
    Si vous pouviez me donner un petit coup de pouce pour cela se serait sympa.

    Ci-dessous le code que j'ai réalisé :

    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
    #! /bin/awk -f
    #! /bin/sed -f
     
    wc -l flux.txt >> analyse
     
    awk '{
    if (length($0) != 13) {
    	awk 'NR==$0, NR==$0{print>\"analyse\"} NR<$0||NR>$0}' flux.txt >> flux.txt
    		} else {
     
    	sed -e '{s/\(.\{33\}\)\(.\{3}\)\(.\{13\}\)\(.\{10\}\)\(.\{4\}\)\(.\{3\}\)\(.\{18\}\)\(.\{1\}\)\(.\{6\}\)/
    		\1|\2|\3|\4|\5|\6|\7|\8|\9/}' 
    		-e '{s/\(.\{99\}\)\(.\{3\}\)\(.\{1\}\)\(.\{5\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/
    		\1|\2|\3|\4|\5|\6|\7|\8|\9/}' 
    		-e '{s/\(.\{157\}\)\(.\{15\}\)\(.\{2\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/
    		\1|\2|\3|\4|\5|\6|\7|\8/}' flux.txt > resultat_flux.txt 
    	}
    }
     
    wc -l resultat_flux.txt
    Merci de votre aide.

  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,

    mon code ne fonctionne absolument pas pour cette partie
    ton script ne fonctionne tout simplement pas du tout.
    c'est un "panachage" (?) de langages shell/awk/sed.

    fais donc tout en bash !!!
    c'est plus lent, mais au moins tu apprendras les mécanismes élémentaires de la programmation shell.
    après, tu pourras utiliser des langages plus évolués comme awk.
    d'abord le B A BA.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

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

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    Citation Envoyé par GrosFlamby Voir le message
    Le problème que je n'arrive pas à résoudre c'est de couper les lignes défectueuses et les insérer dans un autre fichier (mon code ne fonctionne absolument pas pour cette partie).
    acté qu'il s'agit d'une question awk,(effectivement comme dit N_BaH c'est un patchwork ton script, ça ne peut pas fonctionner) par "couper" si on entend simplement ne pas les afficher c'est assez simple, s'il s'agit d'en prendre une portion la fonction substr() devrait pouvoir aider, quant à l'ajouter à un autre fichier, une syntaxe du genre print "machin" >> "fichier" est valide

  4. #4
    Membre expérimenté Avatar de silfun1
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mars 2015
    Messages
    135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2015
    Messages : 135
    Par défaut
    Salut à tous, Salut GrosFlamby,

    Peux tu envoyer un extrait de ton fichier flux.txt ?

    Voici un bout de code qui peut t'aider (je ne l'ai pas testé)
    ps: je n'ai pas touché à ta commande sed, car tu dis qu'elle fonctionne

    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
    #!/bin/bash
     
    # Varaibles
    src_filename="flux.txt"
    result_file="resultat_flux.txt"
    analyse_file="analyse"
    tempfile="flux.tmp"
    longueur_max=13
     
    #Create the analyse file / creation du fichier analyse
    echo "" > $analyse_file
    #Create the result file / creation du fichier de resultats
    echo "" > $result_file
    #Create the temp file / creation du fichier temporaire
    echo "" > $tempfile
     
    #Main action
     
    # Read each line of the text file / lit chaque lignes du fichier texte
    while read -r line
    do
            # get the lenght of the line / recupere la longueur de la ligne
            linesize=${#line}
     
            # Si la longuere de la ligne est superieure Ã*3 (la limite),alors on copie la ligne ds le fichier analyse
            if [ $linesize -gt $longueur_max ]; then
                    echo $line >> $analyse_file
            else
                    # Sinon on ajoute la ligne dans un fichier temp que la commande sed traitera
                    echo $line >> $tempfile
            fi
     
    done < "$src_filename"
     
    # Insert pipe characters / on insert des caracteres pipes
    sed -e '{s/\(.\{33\}\)\(.\{3}\)\(.\{13\}\)\(.\{10\}\)\(.\{4\}\)\(.\{3\}\)\(.\{18\}\)\(.\{1\}\)\(.\{6\}\)/\1|\2|\3|\4|\5|\6|\7|\8|\9/}' -e '{s/\(.\{99\}\)\(.\{3\}\)\(.\{1\}\)\(.\{5\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/\1|\2|\3|\4|\5|\6|\7|\8|\9/}' -e '{s/\(.\{157\}\)\(.\{15\}\)\(.\{2\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/\1|\2|\3|\4|\5|\6|\7|\8/}' $tempfile
    Syl

  5. #5
    Candidat au Club
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Avril 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Avril 2016
    Messages : 3
    Par défaut
    Merci à tous pour vos réponses.

    J'ai suivi vos conseils et j'ai simplifié le code. Maintenant il fonctionne même si ce n'est pas optimal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #! /bin/bash
     
    wc -l fluxbig.txt >> analyse   # décompte des lignes dans le fichier d'origine
     
    egrep -nv '^.{250}$' < fluxbig.txt >> analyse  # envoie des lignes qui ne font pas 250 caractères de long dans le fichier "analyse" avec le numéro de ligne
    egrep '^.{250}$' < fluxbig.txt | sed -e '{s/\(.\{33\}\)\(.\{3}\)\(.\{13\}\)\(.\{10\}\)\(.\{4\}\)\(.\{3\}\)\(.\{18\}\)\(.\{1\}\)\(.\{6\}\)/ \1|\2|\3|\4|\5|\6|\7|\8|\9/}' 
    		                                    -e '{s/\(.\{99\}\)\(.\{3\}\)\(.\{1\}\)\(.\{5\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/ \1|\2|\3|\4|\5|\6|\7|\8|\9/}' 
    		                                    -e '{s/\(.\{157\}\)\(.\{15\}\)\(.\{2\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/  \1|\2|\3|\4|\5|\6|\7|\8/}' flux.txt > resultat_flux.txt     # si la ligne fait 250 caractère, on applique l'insertion du séparateur (pipe) à des intervalles réguliers, puis on envoie le résultat dans le fichier "resultat flux"
     
    wc -l resultat_flux.txt >> analyse  # décompte des lignes du fichier généré pour comparer avec e fichier d'origine
    Voila voila, je le retravaille pour l'optimiser de temps en temps mais je n'en ai pas toujours le temps.

    Je vais tester ta proposition silfun1 et je te tiens au courant.

    Merci à tous en tout cas

  6. #6
    Candidat au Club
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Avril 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Avril 2016
    Messages : 3
    Par défaut
    Merci à tous pour vos réponses.

    J'ai suivi vos conseils et j'ai simplifié le code. Maintenant il fonctionne même si ce n'est pas optimal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #! /bin/bash
     
    wc -l fluxbig.txt >> analyse   # décompte des lignes dans le fichier d'origine
     
    egrep -nv '^.{250}$' < fluxbig.txt >> analyse  # envoie des lignes qui ne font pas 250 caractères de long dans le fichier "analyse" avec le numéro de ligne
    egrep '^.{250}$' < fluxbig.txt | sed -e '{s/\(.\{33\}\)\(.\{3}\)\(.\{13\}\)\(.\{10\}\)\(.\{4\}\)\(.\{3\}\)\(.\{18\}\)\(.\{1\}\)\(.\{6\}\)/ \1|\2|\3|\4|\5|\6|\7|\8|\9/}' 
    		                   -e '{s/\(.\{99\}\)\(.\{3\}\)\(.\{1\}\)\(.\{5\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/ \1|\2|\3|\4|\5|\6|\7|\8|\9/}' 
    		                   -e '{s/\(.\{157\}\)\(.\{15\}\)\(.\{2\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/  \1|\2|\3|\4|\5|\6|\7|\8/}' flux.txt > resultat_flux.txt     # si la ligne fait 250 caractère, on applique l'insertion du séparateur (pipe) à des intervalles réguliers, puis on envoie le résultat dans le fichier "resultat flux"
     
    wc -l resultat_flux.txt >> analyse  # décompte des lignes du fichier généré pour comparer avec e fichier d'origine
    Voila voila, je le retravaille pour l'optimiser de temps en temps mais je n'en ai pas toujours le temps.

    Je vais tester ta proposition silfun1 et je te tiens au courant.

    Merci à tous en tout cas

  7. #7
    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
    Bonjour,

    Si ton script est exactement ce que tu donnes dans ton dernier post, celui-ci ne fonctionne certainement pas comme tu le souhaites, car le sed ne traite pas la sortie de ton egrep mais le fichier flux.txt.
    De plus, es-tu certain de tes positions pour la deuxième et troisième commande de sed, car la première commande rajoute les premiers pipe qui doivent être pris en compte lors des commandes suivantes et ainsi de suite ?

    Sinon, comme proposé par N_BaH, qui se lance pour une version total bash (built-in) ?

  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
    Pour le fun, juste avec sed (attention, ça pique les yeux ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sed -n '$=' fluxbig.txt | sed -s '=' - fluxbig.txt | sed -ne '2 s/$/ fluxbig.txt/w analyse' \
    -e '3~2 {N;/\n.\{250\}$/s/.*\n//;t cont;s/\n/ /w analyse' \
    -e ';t;:cont' -e 's/\(.\{33\}\)\(.\{3\}\)\(.\{13\}\)\(.\{10\}\)\(.\{4\}\)\(.\{3\}\)\(.\{18\}\)\(.\{1\}\)\(.\{6\}\)/ \1|\2|\3|\4|\5|\6|\7|\8|\9/' \
    -e 's/\(.\{99\}\)\(.\{3\}\)\(.\{1\}\)\(.\{5\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/ \1|\2|\3|\4|\5|\6|\7|\8|\9/' \
    -e 's/\(.\{157\}\)\(.\{15\}\)\(.\{2\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{10\}\)\(.\{1\}\)/  \1|\2|\3|\4|\5|\6|\7|\8/p;}' >resultat_flux.txt

Discussions similaires

  1. Réponses: 3
    Dernier message: 22/02/2015, 12h01
  2. Réponses: 2
    Dernier message: 26/06/2012, 10h46
  3. [XL-2007] Copier des données d'un classeur et les coller dans un autre
    Par Runsh63 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 12/06/2012, 06h18
  4. Réponses: 2
    Dernier message: 03/04/2010, 22h32
  5. [XL-2003] copier toutes les lignes concernées et les coller dans un autre onglet
    Par spacesheep dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 30/10/2009, 15h40

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