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 :

tr: supprimer LF en fin de ligne


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 42
    Par défaut tr: supprimer LF en fin de ligne
    Bonjours,

    J'ai un fichier ou le champ séparateur est | et il est présent après le dernier champ.
    Je cherche a compter le nombre de champ sur la première ligne qui a ce format:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     head -n 1 ../tmp/TATA_20080830120000.log
    TATA||2008-08-19 00:00:55|16|1|login|TITI|TOTO|TUTU|13|301||1||
    Comme vous pouvez le constater, Il me suffit de compter ne nombre de | pour avoir le nombre de champs.(dans ce cas 14)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    head -n 1 ../tmp/TATA_20080830120000.log| sed -e 's/[^'$"|"']//g' |wc -m
    15
    Apres analyse, la commande head rajoute un caractère non imprimable de fin de ligne LF.

    J'ai donc tenté de rediriger vers tr:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    head -n 1 ../tmp/TATA_20080830120000.log| sed -e 's/[^'$"|"']//g' |tr -d \r | wc -m
    15
    D'où ma question: comment éliminer le caractère LF ?
    J'ai lu dans le man tr qu'on pouvait éliminer un caractère avec son code hexa mais ca ne marche pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    head -n 1 ../tmp/TATA_20080830120000.log| sed -e 's/[^'$"|"']//g' |tr -d \0x0A | wc -m
    15
    Quelqu'un a une solution ?

    Eric.

  2. #2
    Membre émérite Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Bonjour,

    C'est bien étrange pour compter le nombre de champs. Une simple commande awk aurait été suffisante.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F '|' '{print NF; exit}' fichier.txt
    Sinon, on peut effectivement supprimer tout ce qui n'est pas '|' puis compter le nombre de caractères. Mais dans ce cas, on peut faire plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    head -1 fichier.txt | sed -e 's/[^|]//g' | wc -m
    Pour la question, la plupart des commandes ajoutent un '\n' (Linux à tout le moins) à la fin de leur sortie pour que le prompt (l'invite) soit bien sur la ligne suivante. Les commandes savent qu'il ne faut pas traiter ce caractère, c'est la fin de la ligne de commande. On peut néanmoins retirer le caractère '\n' de la sortie de la commande head en utilisant tr. Attention cependant à bien mettre les quotes (guillemets) autour du caractère spécial \n.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    head -n 1 ../tmp/TATA_20080830120000.log | sed -e 's/[^'$"|"']//g' | tr -d '\n' | wc -m
    L'on remarque alors que le prompt n'est plus sur la ligne suivante mais à la fin de la sortie des commandes.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 42
    Par défaut
    Je crois que je me suis très mal exprimé.

    J'ai fait deux scripts de test pour illustrer mon propos:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    # ls testTri*
    testTri:
    test         testTri.sh*
     
    testTri2:
    test          testTri2.sh*
    Le fichier test contient les même info (3 champs par ligne) dans les deux cas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    cat testTri2/test
    champ1|champ2|champ3|
    champ4|champ5|champ6|
    voici le code de testTri.sh
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    cat testTri/testTri.sh
    #!/bin/bash
     
    for iFic in `ls test` ; do
            cat $iFic | while read ligne ; do
                    nb=$(echo -n $ligne| sed -e 's/[^'$"|"']//g' | wc -m)
                    echo "nb="$nb " iFic="$iFic
            done
    done
    et le résultat de son appel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    cd testTri/
    vke00@152101a121 /app/vke00/tmp/testTri oxe11 # ./testTri.sh
    nb= 3  iFic=test
    nb= 3  iFic=test
    Ce script boucle sur chaque lignes du fichier et compte le nombre de pipe.

    Je veux le modifier afin qu'il ne boucle plus sur les lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     cat testTri2/testTri2.sh
    #!/bin/bash
     
    for iFic in `ls test` ; do
            nb=$(head -n 1 $iFic| sed -e 's/[^'$"|"']//g' | wc -m)
            echo "nb="$nb " iFic="$iFic
    done
    et voici le resultat de son appel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     ./testTri2.sh
    nb= 4  iFic=test
    Il compte un pipe de trop !

    Quand à awk, j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    awk -F '|' '{print NF; exit}' test
    4
    Donc encore 1 de trop !

    C'est très tétrange, non ?

    Précision: je suis sous AIX, mais je ne pense pas que cela pose problème.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 42
    Par défaut
    autant pour moi,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    head -n 1 test | sed -e 's/[^'$"|"']//g' | tr -d '\n' | wc -m
    nb= 3  iFic=test
    Marche très bien !

    J'ai tout de même deux points qui me chiffonnent:
    1/ comment savoir si une commande rajoute LF "à la fin" ? Et dans ce cas, qui rajoute LF ? Dans testTri.sh, pourquoi n'y a t'il pas de LF rajouté par sed ?
    2/Où dans la donc est-il indiqué que je devais mettre des quotes autours de \n ?

    Encore merci,

    Eric.

  5. #5
    Membre émérite Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Pour le point 1: La plupart des commandes ajoutent un retour à la ligne (newline) à la fin de leur sortie, sauf echo -n "coucou" ou printf "coucou".

    Pour le point 2: man bash. Lors de la commande tr -d \n, l'interpréteur lance la commande tr avec l'option -d et le paramètre n, c'est-à-dire qu'il lance réellement tr -d n. Pourquoi? Parce qu'il existe des méta-caractères: ce sont des caractères avec une signification spéciale (| & ; ( ) < > espace tab). Mais pour représenter les vrais caractères et pas leur signification spéciale, il faut les échapper avec un \ devant, donc \ permet d'obtenir le vrai caractère qui suit. C'est pourquoi \n devient n. En ajoutant les guillemets, on interdit à l'interpréteur d'aller tenter de modifier ce qu'on veut passer à la commande.

    Un autre point: Pourquoi écris-tu l'expression régulière /[^'$"|"']/ ? À l'intérieur des guillemets de sed, le caractère '|' n'est plus un méta-caractère. Par conséquent il est loisible d'écrire /[^|]/.

  6. #6
    Membre émérite Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    pour le \n à la fin, dès qu'il y en a un, aucun autre n'est ajouté.
    echo ajoute un \n à toto, grep n'ajoute rien.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo -n toto | grep toto
    echo -n n'ajoute pas le \n, alors grep le fait.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 42
    Par défaut
    Citation Envoyé par jmelyn Voir le message

    Un autre point: Pourquoi écris-tu l'expression régulière /[^'$"|"']/ ? À l'intérieur des guillemets de sed, le caractère '|' n'est plus un méta-caractère. Par conséquent il est loisible d'écrire /[^|]/.
    En fait, je ne suis pas l'auteur du script initial...
    L'expression régulière est "remplace tout ce qui n'est pas un pipe par rien".
    Il aurait effectivement été plus judicieux d'écrire "sélectionne tous les pipes"
    Pour les guillemet...heu...je ne suis pas l'auteur (et je n'ai pas l'occasion de le contacter), je ne suis pas très futé non-plus...

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/07/2011, 09h37
  2. [CS3] Comment supprimer les "^M" en fin de ligne de code HTML ?
    Par byloute dans le forum Dreamweaver
    Réponses: 0
    Dernier message: 12/02/2010, 14h55
  3. Supprimer les espaces en fin de ligne
    Par papyreno dans le forum Eclipse Java
    Réponses: 8
    Dernier message: 21/02/2008, 22h11
  4. Supprimer le tiret de coupure des mots en fin de ligne
    Par Dagnan dans le forum Mise en forme
    Réponses: 1
    Dernier message: 09/05/2007, 02h13
  5. Supprimer les caractères blancs en fin de ligne
    Par st20085 dans le forum Eclipse Java
    Réponses: 7
    Dernier message: 06/09/2006, 22h51

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