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 :

Supprimer les retours à la ligne


Sujet :

Shell et commandes GNU

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut Supprimer les retours à la ligne
    Bonsoir,

    J'ai un sérieux problème pour traiter un fichier.
    Voici son contenu initial :

    AAAAAAAAA
    $$$BBBBBBB
    $$$CCCCCC
    $$$DDDDDD
    EEEEEEEEEE
    FFFFFFFFFF
    $$$GGGGGG
    HHHHHHHHH
    $$$IIIIIIIIIII
    $$$JJJJJJJJJ

    J'aimerai retraiter ce fichier pour obtenir le résultat suivant :

    AAAAAAAAABBBBBBBCCCCCCDDDDDD
    EEEEEEEEEE
    FFFFFFFFFFGGGGGG
    HHHHHHHHHIIIIIIIIIIIJJJJJJJJJ

    Ce qui revient à dire que je souhaite supprimer le retour chariot d'un enregistrement dès lors que la ligne qui le suit commence par $$$.

    Avez-vous une idée comment le faire ?

    Merci d'avance pour votre aide.

  2. #2
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bonsoir,



    Il suffit de remplacer ’\n$$$’ par "" dans la chaîne de caractères qui constitue la base du fichier.



    Il faut lire cette chaîne, la traiter par une fonction replace() et réécrire la chaîne dans le fichier.

    Il ne faut surtout pas rentrer dans un programme qui examine les lignes l’une après l’autre.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    Je suis à la recherche des commandes unix qui me permettront d'obtenir ce résultat.

  4. #4
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Normalement c'est réalisable avec un sed multiligne, mais je suis un peu rouillé de ce coté là.

    alors voici une solution possible en perl que l'on peut trouver facilement sur des plate formes unix.

    Ce n'est pas la plus élégante façon de faire, cela fait longtemps que je n'ai pas fait de perl, mais elle répond a ton besoin. ce script suppose que ton fichier s'appelle "titi"
    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
     
    #!/bin/perl
     
    #ouverture du fichier
    open(FILE,"titi") || die ("Erreur d'ouverture du fichier");
     
    # lecture du contenu dans un tableau.
    @fileContent = <FILE>;
     
    # fermeture du fichier.
    close FILE;
     
    # parcours du tableau.
    for ($i=0; $i < @fileContent ; $i++) {
     
     # initialisation de la ligne.
     $line = $fileContent[$i];
     
     # recherche des lignes suivante commencant par $$
     for ($j = $i + 1; $j < @fileContent ; $j++) {
     
         if ($fileContent[$j] =~ /^\$\$/) {
             #*la ligne suivante contiens $$
             #*on les supprime
    	 $fileContent[$j] =~ s/^\$\$//;
             # on la concatene a la ligne courante
    	 $line = $line . $fileContent[$j];
             # on vire les saut de ligne.
    	 $line =~ s/\n//;
             #*on incrémente i pour ne pas la prendre en compte  
             # lors du retour a la boucle principale 
    	 $i++;
         } else {
             #*cette ligne ne commence pas pas $$, fin de la chaine 
             #*et retour à la boucle principale.
    	 last;
         }
     }
     # affichage de la ligne lue
     print $line;
    }
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  5. #5
    Membre averti Avatar de exodev
    Inscrit en
    Septembre 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Septembre 2009
    Messages : 201
    Points : 359
    Points
    359
    Par défaut
    Hello,

    avec bash et quelques lignes
    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
     
    #!/bin/bash
     
    firstLine=1;
    while read line; do
    	if [[ ${line:0:3} == "\$\$\$" ]]; then
    		echo -n "${line:3}";
    	elif [[ $firstLine -eq 1 ]]; then
                    # cas de la premiere ligne
    		echo -n "$line";
    	else
    		echo -ne "\n$line";
    	fi
    	firstLine=0;
    done < data.txt

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 556
    Points : 19 396
    Points
    19 396
    Par défaut
    ceci semble fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    echo 'AAAAAAAAA
    $$$BBBBBBB
    $$$CCCCCC
    $$$DDDDDD
    EEEEEEEEEE
    FFFFFFFFFF
    $$$GGGGGG
    HHHHHHHHH
    $$$IIIIIIIIIII
    $$$JJJJJJJJJ' | sed ':mark;N;/\$\$\$/s/\n$$$\(.*\)/\1/;bmark'
    AAAAAAAAABBBBBBBCCCCCCDDDDDD
    EEEEEEEEEE
    FFFFFFFFFFGGGGGG
    HHHHHHHHHIIIIIIIIIIIJJJJJJJJJ
    quelques liens utiles :
    /usr/share/doc/sed/sed*/sed.html
    http://sed.sourceforge.net/sed1line_fr.html
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre régulier
    Avatar de debianhunter
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 63
    Points : 87
    Points
    87
    Par défaut
    Un petit script sed (pour se derouiller ;o) )
    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
    # cat > script
    #line does not starts with $$$
    /^\$\$\$/!{
    #invert pattern buffer and hold to get previous buffer
       x
    #make change to pattern
       s/\n\$\$\$//g
    #print pattern
       p
    }
    #line starts with $$$
    /^\$\$\$/ {
    #append to hold buffer
       H
    }
    # cat plop
    AAAAAAAAA
    $$$BBBBBBB
    $$$CCCCCC
    $$$DDDDDD
    EEEEEEEEEE
    FFFFFFFFFF
    $$$GGGGGG
    HHHHHHHHH
    $$$IIIIIIIIIII
    $$$JJJJJJJJJ
    
    # sed -n -f script plop
    
    AAAAAAAAABBBBBBBCCCCCCDDDDDD
    EEEEEEEEEE
    FFFFFFFFFFGGGGGG
    HHHHHHHHHIIIIIIIIIIIJJJJJJJJJ
    #
    Un peu de lecture.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    Merci à vous tous pour les réponses.
    J'ai désormais le choix.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    sed ':mark;N;/\$\$\$/s/\n$$$\(.*\)/\1/;bmark'

    Je dois admettre que sed est vraiment puissant.
    A chaque fois que je vois une expression en sed, je suis impressionné par sa puissance.

    Pourriez-vous m'expliquer comment interpréter oralement cette solution ?
    Que veut dire marK ? et le reste d'ailleurs ?

    Merci

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    J'ai un autre cas :

    DEBUTAAAAAAAAA
    BCCCCCCC
    DEBUTDDDDDDD
    DEBUTEEEEEEEE
    DEBUTFFFFFFFFFFFFF
    GHHHHHHHHHHH
    IJJJJJJJJJJJJJJJJ

    Je cherche à obtenir le résultat suivant :

    DEBUTAAAAAAAAABCCCCCCC
    DEBUTDDDDDDD
    DEBUTEEEEEEEE
    DEBUTFFFFFFFFFFFFFGHHHHHHHHHHHIJJJJJJJJJJJJJJJJ

    En bref, toute ligne qui ne commence pas par DEBUT doit être rattachée ou concaténer à la ligne qui la précède et qui commence par DEBUT.

    Merci infiniment pour votre aide

  11. #11
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Le premier traitement peut se faire sans expression régulière.

    Mais le second traitement est plus difficile à faire sans expression régulière.

    En Python:



    premier traitement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    with open('nom_fichier.txt','rb+') as f:
        ch = f.read()
        ch = ch.replace('\r\n$$$','').replace('\r$$$','')
        f.seek(0)
        f.write(ch)
        f.truncate()

    second traitement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    with open('nom_fichier2.txt','rb+') as f:
        ch = f.read()
        ch = re.sub('\r?\n(?!DEBUT)','',ch)
        f.seek(0)
        f.write(ch)
        f.truncate()


    Les fichiers Windows ont des fins de ligne ’\r\n’ , tandis que les fichiers Apple n’ont que ’\r’ comme fin de ligne.
    Les deux codes ci-dessus sont écrits de façon à pouvoir traiter aussi bien un type de fichier que l’autre.

  12. #12
    Membre averti Avatar de exodev
    Inscrit en
    Septembre 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Septembre 2009
    Messages : 201
    Points : 359
    Points
    359
    Par défaut
    pour rester dans la lignée de mon script bash du dessus (avant que la commande sed d'une ligne ne vienne encore casser tout le reste )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/bin/bash
     
    firstLine=1;
    while read line; do
    	if [[ $firstLine -eq 1 ]]; then
    		echo -n "$line";
                    firstLine=0;
    	elif [[ ${line:0:5} == "DEBUT" ]]; then
    		echo -ne "\n${line}";
    	else
    		echo -n "$line";
    	fi
    done < data.txt

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 556
    Points : 19 396
    Points
    19 396
    Par défaut
    je n'ai pas encore trouvé en sed

    en bash :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    while read line
    do [[ "$line" == DEBUT* ]] && keep[++n]="$line" || keep[n]+="$line"
    done <<<'DEBUTAAAAAAAAA
    BCCCCCCC
    DEBUTDDDDDDD
    DEBUTEEEEEEEE
    DEBUTFFFFFFFFFFFFF
    GHHHHHHHHHHH
    IJJJJJJJJJJJJJJJJ'
    printf '%s\n' "${keep[@]}"
    DEBUTAAAAAAAAABCCCCCCC
    DEBUTDDDDDDD
    DEBUTEEEEEEEE
    DEBUTFFFFFFFFFFFFFGHHHHHHHHHHHIJJJJJJJJJJJJJJJJ
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 556
    Points : 19 396
    Points
    19 396
    Par défaut
    Ah! en sed :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    sed ':mark;N;/\nDEBUT/!{N;s/\n//g; /.*DEBUT.*/s/\(DEBUT.*\)\(DEBUT.*\)/\1\n\2/; bmark}' <<<<'DEBUTAAAAAAAAA
    BCCCCCCC
    DEBUTDDDDDDD
    DEBUTEEEEEEEE
    DEBUTFFFFFFFFFFFFF
    GHHHHHHHHHHH
    IJJJJJJJJJJJ'
    DEBUTAAAAAAAAABCCCCCCC
    DEBUTDDDDDDD
    DEBUTEEEEEEEE
    DEBUTFFFFFFFFFFFFFGHHHHHHHHHHHIJJJJJJJJJJJ
    ok, ça fait un peu bricolage

    mark est une étiquette pour la commande b, qui crée une boucle inconditionnelle (une sorte de GOTO).
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    Voici ce que me retoune unix quand je lance la commande.
    Label too long: :mark;N;/\$\$\$/s/\n$$$\(.*\)/\1/;bmark

    Vous avez une idée ?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 556
    Points : 19 396
    Points
    19 396
    Par défaut
    désolé, je n'ai pas de sed non-GNU.

    essaie de remplacer 'mark' par un seul caractère alphabétique...
    ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    J'ai changé :mark;N;/\$\$\$/s/\n$$$\(.*\)/\1/;bmark
    par
    :L;N;/\$\$\$/s/\n$$$\(.*\)/\1/;bL
    et toujours la même erreur.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 556
    Points : 19 396
    Points
    19 396
    Par défaut
    peut-être en ajoutant un point-virgule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed ':mark;N;/\$\$\$/s/\n$$$\(.*\)/\1/;bmark;'
    ...
    ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Août 2009
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 80
    Points : 88
    Points
    88
    Par défaut
    Toujours le même problème, même avec le ";" en plus.
    Sur une plate-forme Linux CentOS, je n'ai pas de problème.
    En revanche, sur une plate-forme Unix Sun, il m'affiche toujours Label too long.

  20. #20
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    salut,

    essaye ceci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    gawk '/^DEBUT/&&NR>1{printf "\n%s",$0;next}{printf $0}' fichier
    <tester sous windows>

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [MySQL] Supprimer les retours à la ligne
    Par p0Kep0K dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 18/06/2012, 11h54
  2. [PHP-JS] Supprimer les retours à la ligne
    Par defacta dans le forum Langage
    Réponses: 3
    Dernier message: 08/10/2007, 13h23
  3. Supprimer les retours à la ligne dans une chaine
    Par koktel_dfr dans le forum C
    Réponses: 22
    Dernier message: 03/05/2007, 10h12
  4. [CSV] supprimer les retours à la ligne
    Par illegalsene dans le forum Langage
    Réponses: 3
    Dernier message: 09/01/2006, 16h14
  5. [RegEx] supprimer les retours à la ligne
    Par illegalsene dans le forum Langage
    Réponses: 4
    Dernier message: 21/10/2005, 10h53

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