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 :

Nombre de lignes vides à la fin d'un fichier


Sujet :

Shell et commandes GNU

  1. #1
    Membre régulier
    Inscrit en
    Décembre 2010
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 258
    Points : 77
    Points
    77
    Par défaut Nombre de lignes vides à la fin d'un fichier
    Bonjour à tous,

    J'aimerais faire un petit shell qui me permet de compter le nombre de ligne vide à la fin d'un fichier.
    J'ai écris quelque chose qui ne marche pas parfaitement. Le but est également de trouver le format des retours charriots (unix ou windows).
    J'ai 3 fichiers, sans.txt, une.txt, deux.txt avec 0, 1 et 2 lignes vides à la fin, de format windows.

    sans.txt
    Nom : mini_382603Capture1.png
Affichages : 1687
Taille : 8,0 Ko

    une.txt
    Nom : mini_490429Capture2.png
Affichages : 1698
Taille : 6,8 Ko

    deux.txt
    Nom : mini_357357Capture3.png
Affichages : 1705
Taille : 6,1 Ko

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    for FILE in `find "." -type f`
    do
    	NAME=`basename "$FILE"`
    	if [ $(tail -n 2 "$FILE" | od -c | grep -F "\r" | wc -l) -eq 1 ]
    	then
    		CHARRIOT="WINDOWS"
    		LIGNE=$(tail -n 2 "$FILE" | od -c | sed "s/ //g" | sed "s/\\\r\\\n/#/g" | grep -o "#" | wc -l)
    	else
    		CHARRIOT="UNIX"
    		LIGNE=$(tail -n 2 "$FILE" | od -c | sed "s/ //g" | sed "s/\\\n/#/g" | grep -o "#" | wc -l)
    	fi
    	echo "$NAME : $CHARRIOT, $LIGNE ligne vide a la fin"
    done
    Voici le résultat erroné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    deux.txt : WINDOWS, 2 ligne vide a la fin
    une.txt : WINDOWS, 2 ligne vide a la fin
    sans.txt : WINDOWS, 1 ligne vide a la fin
    Peut-être y'a t-il un moyen plus simple ?
    Merci d'avance

  2. #2
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 459
    Points
    13 459
    Par défaut
    Bonjour,

    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
    $ cat /tmp/toto.txt
    df
     
    dfg
    df
     
     
    dsfg
     
     
    dfsg
     
     
     
    $ tac /tmp/toto.txt |sed -n '/[^ \t]/q;p'|wc -l
    3
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ todos ./"$fichier"
    $ file -b ./"$fichier" 
    ASCII text, with CRLF line terminators
    $ fromdos ./"$fichier"
    $ file -b ./"$fichier" 
    ASCII text
    $
    $ cp ./"$fichier" ./"$fichier".plus
    $ echo -e "\n\n\n" >>./"$fichier".plus
    $ sed -n '$=' ./"$fichier".plus
    12
    $ sed -n ':c;N;$!bc;s/\n*$//p' ./"$fichier".plus | sed -n '$='
    8
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    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 287
    Points : 12 744
    Points
    12 744
    Par défaut
    Bonjour,

    Si on ne trie pas le fichier, on peut le faire avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    uniq -c fichier | tail -1
    ceci donnera la dernière ligne préfixée du nombre de fois qu'elle est répétée à la fin du fichier en question
    Cordialement.

  5. #5
    Membre régulier
    Inscrit en
    Décembre 2010
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 258
    Points : 77
    Points
    77
    Par défaut
    Merci pour vos réponses, mais après avoir tester sur mon exemple ça ne fonctionne pas..

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    «ça marche pas»

    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre régulier
    Inscrit en
    Décembre 2010
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 258
    Points : 77
    Points
    77
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    bash-3.2$ tac sans.txt |sed -n '/[^ \t]/q;p'|wc -l
    0
    bash-3.2$ tac une.txt |sed -n '/[^ \t]/q;p'|wc -l
    0
    bash-3.2$ tac deux.txt |sed -n '/[^ \t]/q;p'|wc -l
    1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    bash-3.2$ sed -n ':c;N;$!bc;s/\n*$//p' sans.txt | sed -n '$='
    3
    bash-3.2$ sed -n ':c;N;$!bc;s/\n*$//p' une.txt | sed -n '$='
    3
    bash-3.2$ sed -n ':c;N;$!bc;s/\n*$//p' deux.txt | sed -n '$='
    3
    Peut-être que c'est moi qui m'en sert mal ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    bash-3.2$ uniq -c une.txt | tail -n 1
          1 sdf
    bash-3.2$ uniq -c deux.txt | tail -n 1
          1
    bash-3.2$ uniq -c sans.txt | tail -n 1
          1 sdf

    EDIT :

    En faisant comme ça c'est moche mais ça 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
     
    if [ $(tail -n 2 "$FILE" | od -c | grep -F "\r" | wc -l) -eq 1 ]
    	then
    		CHARRIOT="WINDOWS"
    		if [ $(tail -n 2 "$FILE" | od -c | sed "s/ //g" | head -n 1 | tail -c -9 | sed "s/\\\r\\\n/#/g") == "##" ]
    		then
    			LIGNE=2
    		elif [ $(tail -n 2 "$FILE" | od -c | sed "s/ //g" | head -n 1 | tail -c -5 | sed "s/\\\r\\\n/#/g") == "#" ]
    		then
    			LIGNE=1
    		else
    			LIGNE=0
    		fi
    	else
    		CHARRIOT="UNIX"
    		if [ $(tail -n 2 "$FILE" | od -c | sed "s/ //g" | head -n 1 | tail -c -5 | sed "s/\\\n/#/g") == "##" ]
    		then
    			LIGNE=2
    		elif [ $(tail -n 2 "$FILE" | od -c | sed "s/ //g" | head -n 1 | tail -c -3 | sed "s/\\\n/#/g") == "#" ]
    		then
    			LIGNE=1
    		else
    			LIGNE=0
    		fi
    	fi

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    j'aurais dû aller au bout de ma démonstration.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ cat > fichier
    1
    2
    3
    4
    5
    6
    7
    8
    $ sed -n '$=' fichier
    8
    $ echo -e "\n\n\n" >> fichier
    $ sed -n '$=' fichier
    12
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo "$(( $(sed -n '$=' fichier) - $(sed -n ':c;N;$!bc;s/\n*$//p' fichier | sed -n '$=') )) ligne(s) vides à la fin du fichier \"fichier\""
    4 ligne(s) vides à la fin du fichier "fichier"
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 459
    Points
    13 459
    Par défaut
    Peut-être que c'est moi qui m'en sert mal ?
    Bien sûr que tu t'en sers mal. Tu vois bien que :
    • la définition de la ligne vide diffère selon les personnes et les systèmes.
    • dans ma solution, il y a, entre crochets [^ ], la liste des caractères n'étant pas une entrave à la qualification de ligne vide.


    Donc, pour ce dernier point, et si tu as toujours des fichiers windows, tu peux rajouter le caractère \r.

    J'avoue avoir mis de la mauvaise volonté. Une ligne qui a un \r n'est pas vide. Je ne vois pas pourquoi je ferais un effort pour windows alors qu'on est sous linux.

    La commande optimale devrait être:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tac /tmp/toto.txt |sed -n '/[^ \t\r]/q;/\r./q;p'|sed -n '$='
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  10. #10
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 287
    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 287
    Points : 12 744
    Points
    12 744
    Par défaut
    Pour ma part, cela fait le job que j'ai précisé, si tu veux que cela fonctionne uniquement pour les chaines vides, il faut amélioré.
    Ce qui n'est pas correcte, ce sont plutôt tes fichiers d'entrées, pourrais-tu nous fournir la sortie de la commande suivante:
    Exemple de code amélioré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    uniq -c <(echo -e "$(<deux.txt)\n\r") | awk 'END{print $1-1}'
    EDIT: Rajout d'une méthode avec awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '{/^\r$/?x++:x=0}END{print x}' fichier
    Cordialement.

Discussions similaires

  1. [XL-2003] Problème de ligne vide (ctrl + fin)
    Par makila64 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 02/07/2012, 15h59
  2. ne pas avoir de lignes vide en fin de page
    Par Louisa2005 dans le forum Word
    Réponses: 4
    Dernier message: 16/03/2010, 22h58
  3. Réponses: 2
    Dernier message: 10/12/2009, 17h05
  4. DataGridView ligne vide à la fin..
    Par lucfrfr dans le forum Windows Forms
    Réponses: 7
    Dernier message: 08/11/2007, 14h35
  5. Sous-Formulaire nombre de lignes vides ?
    Par popo68 dans le forum IHM
    Réponses: 25
    Dernier message: 11/12/2006, 09h28

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