[shell unix] fichier ligne par ligne

Résolu
jebok Messages postés 371 Date d'inscription   Statut Membre -  
 SinD -
Bonjour,

comment faire défiler un fichier ligne par ligne, de manière à traiter chaque ligne ?

--
Merci de votre aide

27 réponses

  • 1
  • 2
Résumé de la discussion

La question porte sur comment lire un fichier ligne par ligne afin de traiter chaque ligne, en recherchant des méthodes simples et efficaces avec des boucles, des redirections et des contrôles d'erreur. Parmi les solutions les plus pertinentes figurent l'utilisation d'une boucle while read ligne dans le shell, ou l'approche cat fichier | while read ligne do ... done, selon le contexte. Des retours évoquent aussi des précautions, notamment que la commande read peut supprimer les espaces en début de ligne et que des variantes existent pour préserver ces espaces selon le shell.

Bobot (l'IA à votre service)
  1. truky Messages postés 45 Statut Membre 34
     
    Je sais que ca remonte a 2006 mais pour les prochains lecteurs

    ben che pas si vous aimez le truc compliqué mais j'ai

    while read a b c
    do 
    echo "$a $b $c"
    done < fichier.txt


    tou simplement

    bye
    34
  2. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Salut,

    Essaie ça :
    [jp@MDK tmpfs]$ cat fich.txt
    
    riri rara roro
    toto tata titi
    lili lala lolo
    
    [jp@MDK tmpfs]$ cat new.sh
    
    #!/bin/bash
    
    while read ligne
    do
    set $(echo $ligne)
    init_prenom=$(eval echo $1)
    prenom=$(eval echo $2)
    nom=$(eval echo $3)
    echo -e "variable1=$init_prenom\nvariable2=$prenom\nvariable3=$nom\n"
    done < fich.txt
    
    [jp@MDK tmpfs]$ sh new.sh
    
    variable1=riri
    variable2=rara
    variable3=roro
    
    variable1=toto
    variable2=tata
    variable3=titi
    
    variable1=lili
    variable2=lala
    variable3=lolo
    
    [jp@MDK tmpfs]$
    ;-))
    24
  3. francis
     
    ça dépand du traitement mais si lire la ligne pour faire une action

    cat FICHIER | while read ligne
    do
    ....
    ....
    #action
    ....
    ....
    done
    19
  4. kelux Messages postés 3065 Date d'inscription   Statut Contributeur Dernière intervention   434
     
    Encore quelques jours et c'était un an pile de retard !

    Ah oui le mode asynchrone c'est gênant des fois...un an apres c'est pas mal quand meme :)
    10
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. kobal
     
    Voici un petit script que j'ai créé grâce à ce fil -décidemment- très utile.

    Il prend une playlist et un repertoire en entrée et copie les fichiers de la playlist dans le repertoire. Tout ça parceque Rhythmbox ne le fait pas tout seul.

    #!/bin/sh
    
    if [ $# -eq 2 ]
    then
    	FILE=$1
    	DIR=$2	
    else
    	echo "$# arguments found, 2 expected."
    	echo "Usage: m3ucp M3U_FILE DESTINATION_DIR"
    fi
    
    if [ -f $FILE ]
    then
    	if [ -d $DIR ]
    	then
    		cat $FILE | while read ligne
    		do
    			cp "$ligne" "$DIR"	
    			echo "Copie de $ligne effectuee"
    		done
    	else
    		echo "$DIR est introuvable"
    	fi
    else
    	echo "$FILE est introuvable"
    fi
    
    9
    1. boop
       
      2009 ce fil est encore très utile!!

      merci a tous !!
      0
    2. ckdevelop
       
      toujours aussi utile
      0
    3. toto
       
      utile encore et toujours
      0
    4. Ektha
       
      A mon avis il sera encore utile d'ici la fin des temps.

      Merci pour votre aide.
      0
    5. Dznet
       
      Janvier 2013 toujours util
      0
  7. darkukai
     
    hi hi hi excellent le retour de la réponse d'outre tombe un an plus tard :)

    bon du coup ce petit re-up du post me convient bien parceque j'ai le même problème si ce n'est que le mien est un peu plus pointu
    j'ai un fichier .csv suivant :
    riri rara roro
    toto tata titi
    lili lala lolo

    j'aimerai lire ligne par ligne ce fichier dans une boucle pour
    au premier passage mettre
    variable1=riri
    variable2=rara
    variable3=roro
    2ème passage:
    variable1=toto
    variable2=tata
    variable3=titi
    etc...

    j'ai reussi a créer la boucle qui va bien pour passer de ligne en ligne comme suit :

    while read ligne
    do
    i=$i+1
    echo $i
    # Définition des variables à partir du fichier list.csv
    #-F ";"
    
    awk '{print $1}' > init_prenom
    init_prenom=$(cat init_prenom)
    echo $init_prenom
    
    awk '{print $2}' > prenom
    prenom=$(cat prenom)
    echo $prenom
    
    awk '{print $3}' > nom
    nom=$(cat nom)
    echo $nom
    done < $fichier
    done
    


    mais ma command awk semble ne pas fonctionner car elle ne me sort aucune valeur du fichier :(

    si quelqu'un a une idée ??

    merci d'avance

    ps : je sais que mon script est tout pourri donc pas de remarque sur l'optimisation c'est juste un truc dont je suis censé me servir une fois pour remplir un annuaire ldap ... avec plein de titi toto lala lili bref je m'amuse :)
    5
  8. lol
     
    Super post bien marrant !!

    il persiste ! Merci ca sert encore !

    et + 1 année :)
    4
  9. NikoBe
     
    note: c'est sans doute "read" qui enlève les espaces en début de ligne aussi
    1
  10. darkukai
     
    OUuuaaaaAAAa

    C'est génial çà marche super au poil :) :)

    merci vraiment merci

    je suis pas un développeur ( nooonnn sans déconner :) ) et j'ai passer toute l'aprem d'hier a essayer de me dépatouiller avec awk sans résultat

    encore merci de ton aide
    @Bientot
    0
  11. Ibrahim
     
    Qui a une idée de comment utilise la boucle for avec le shell unix Merci
    0
  12. visiteur
     
    Le sujet date de plus de deux ans maintenant, la reponse de celui qui l'a initié a été un an plus tard, pourtant moi au jour d'aujourd'hui en 2007 ça me sert ce sujet, et null doute que des personnes qui auront besoin de ce sujet seront enthousiasmées de trouver cette solution, des années aprés et pourquoi pas des décennies aprés, vue qu'Internet est devenu le seul outil immortel que l'homme ait inventé.

    Je tiens quand même a remercier les personnes qui ont initiées ce sujet, et celles et ceux qui ont apportées leurs contributions.

    Bien à vous.
    0
    1. dam
       
      Merci ca sert encore et encore.
      0
    2. Micka
       
      et toujours!
      0
    3. OHSECOURS
       
      et encore !
      0
    4. NikoDinaz
       
      et encore !!!
      0
    5. erilanel
       
      et encore merci à tous....
      0
  13. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Et ça va servir encore l'année prochaine, et ainsi de suite..... :-))
    0
  14. Petrio42 Messages postés 11 Statut Membre
     
    bonjour,

    Dans un dossier se trouver des fichiers. J'aimerais trouver une commande en shell qui me permetterer de supprimer les fichier qui date de plus de deux jour(Pour savoir je vais comparer la date de creation du fichier depuis 1970 et le jour que nous somme depuis 1970). Comme le nombre de fichier dans le dossier est variable (car il s'agit du dossier recuperant les fichier uploader) je pense faire une boucle mais je sai pas du tout comment faire quelqu'un pourait-il m'aider.

    Voila se que j'ai commencer a faire

    #!/bin/sh

    datecre=`stat -c $Y /var/www/html/upload/files/* #met en variable le nombre de seconde du fichier depuis 1970`

    nbdefichier=`find /var/www/html/upload/files/ -type f | wc -l`#donne le nombre de fichier dans le dossier

    seconde1970=`date +%s` #met le nombre de seconde en variable depuis 1970

    ((jour1970=$seconde1970/86400)) #on converti les sec en heur

    ((jourfichier=$datecre/86400)) #on fait pareil pour les fichiers dans le dossier

    echo "nous avons $nbdefichier dans le dossier"
    echo "Date de creation des fichiers dans le dossier = $jourfichier"
    echo "Jour depuis 1970 = $jour1970"

    Voila se que j'ai commencer a faire tout cela marche bien quant il n'y a qu'un seul ficiher il me donne bien sa date en jour depuis 1970 mais des que j'en rajoute plus rien ne marche je pense mettre une boucle mais je ne sais pas comment faire .

    Merci d'avance
    0
    1. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
       
      Salut,

      Voir la FAQ : Comment lire un fichier ligne par ligne

      ;-))
      0
      1. Petrio42 Messages postés 11 Statut Membre > jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention  
         
        merci pour cette reponse rapide je vais regarder un peu tout sa
        0
    2. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
       
      la commande find fait la boucle toute seule
      find . -type f -ctime +2 -print
      ajouter, pour supprimer les fichiers:
      -exec rm {} \;
      sinon une boucle en sh:
      for N in liste_de_fichier
      do
      ...
      done
      0
  15. dublin
     
    Bonjour

    Ce cas est un peu différent...
    J'ai un répertoire dans lequel je peux avoir jusqu'à 10 000 fichiers dont les noms se ressemblent
    F09782467
    F09548942
    F09452118
    ...

    Je voudrais récupérer le nom de chaque fichiers 1 à 1 dans une variable pour en faire un traitement.

    num=`ls |wc -w` #je compte le nb de fichiers

    for i in num
    do
    #récupérer le 1er fichier du répertoire
    php -q $fich (...)
    rm -f $fich
    done
    0
    1. challenger90
       
      le for du shell ne fonctionne pas comme celui du dos.
      Voila le bon script :

      for fich in *
      do
      php -q $fich
      rm -f $fich
      done
      0
  16. pidjean
     
    Bonjour
    Voila je veux lire le fichier printed.log ligne par ligne et récuperer une valeur sur une autres serveur par un rsh ( pas de ssh sur cette machine).
    Cela ne fonctionne que pour la premiere ligne.
    Si je retire la ligne contenant rsh le fichier est bien lu en entier.

    merci par avance et que ce post vive encore longtemps

    while IFS=, read destination propri id
    do
    echo $id
    submitt=`rsh serveurid pdls -r heure-soumission -U serveurid:$id |awk -F "'" ' {print$2}'`
    echo $submitt
    done < ./printed.log
    0
  17. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    essayer avec
    submitt=`rsh serveurid pdls -r heure-soumission -U serveurid:$id |awk -F "'" ' {print$2}' < /dev/null`
    0
  18. pidjean
     
    c'est un probleme avec rsh
    avec le flag -n cela fonctionne

    -n
    Specifies that the rsh command should not read from standard input.

    longue vie a ce topic
    0
    1. NikoBe
       
      Pour que ce topic vive encore longtemps !

      J'ai un problème qui m'énerve:
      Je veux lire ligne par ligne un fichier et faire un grep sur chaque ligne (si la ligne contient un certain string alors je rajoute une ligne au fichier).
      Le problème est que la commande "echo" retire les blancs en début de ligne s'ils existent, ce que je ne veux pas !!

      cat monfichier.txt | while read ligne; do
      res=`echo $ligne | grep "^.....coucou"`
      if $res != ""; then
      ... traitement
      fi
      done

      Ce qui ne me renvoit rien pcq echo a retirer tous les blancs en début de $ligne

      Comment faire alors ??


      Un tout grand merci d'avance
      0
    2. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898 > NikoBe
       
      Salut,

      Il ressemble à quoi ton fichier ?
      Les "...." devant "coucou" c'est censé être des espaces ?

      Déjà avec "echo -e" ça devrait aller mieux, mais y'a plus simple que ta syntaxe...
      0
    3. NikoBe > jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention  
       
      OK, je suis pas du tout expert en script shell. Qu'est-ce qui serait plus simple comme syntaxe alors ?
      0
    4. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898 > NikoBe
       
      Peux-tu répondre à la question :
      Les "...." devant "coucou" c'est censé être des espaces ?
      Ou même afficher (entre balise code) un morceau de ton fichier s'il te plaît, merci.
      0
    5. NikoBe > jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention  
       
      Bonjour,

      mon fichier ressemble à qqch comme ceci:

            * TABLES
            *=======
                 @TABCOPY,ABCDEF.
                 @TABCOPY,GHIJKLM.
             coucou.
                 @TABCOPY,NOPQRS.
                 @TABCOPY,TUVWXY.
      


      le traitement à faire porte sur un fichier bien plus grand bien-sûr ^^

      Les "......." devant coucou servent à représenter "n'importe quelle séquence de 7 caractères quels qu'ils soient".
      On pourrait très bien mettre des espaces à la place pour faire le test


      Merci bcp !
      0
  19. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Ok, essaies ça alors :

     ssh$ cat plop
          * TABLES
          *=======
               @TABCOPY,ABCDEF.
               @TABCOPY,GHIJKLM.
           coucou.
    a_2;-:/coucou.
               @TABCOPY,NOPQRS.
               @TABCOPY,TUVWXY.
    
     ssh$ cat foo.sh
    #! /bin/sh
    
    #set -xv
    
    OIFS=$IFS
    IFS=$'\n'
    for line in $(cat plop)
    do
    grep -q '^.\{7\}coucou' <<<"${line}"
    if [ "$?" != 1 ]
            then
            echo "${line}"
    fi
    done
    
     ssh$ ./foo.sh
           coucou.
    a_2;-:/coucou.
    

    ;-))
    0
  • 1
  • 2