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 :

Script création CSV


Sujet :

Shell et commandes GNU

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut Script création CSV
    Bonjour,

    Je voudrais créer un script shell me permettant de faire une liste des répertoires les classant par nom puis lister les fichiers qui sont dans chaque répertoires par taille. Et tout ceci dans un fichier.csv.

    Cela donnerai quelque chose comme ça:

    Rep 001
    fichier 001
    fichier 002
    fichier 003
    fichier 004
    Rep 002
    fichier 001
    fichier 002
    fichier 003
    Rep 003
    fichier 001
    fichier 002
    fichier 003
    fichier 004
    ...

    En fait le problème ne vient pas des commandes mais de la logique.
    Je n'ai aucune logique de prog et là je ne m'en sort pas du tout.

    Merci

  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,

    Est-ce que la commande ls -R1 > mon_fichier.csv est suffisante?

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut
    Citation Envoyé par jmelyn Voir le message
    Bonjour,

    Est-ce que la commande ls -R1 > mon_fichier.csv est suffisante?
    Non car si je fais un simple commande ls -lR1 > file.csv ou ls -lR1S > file.csv cela me classe tout de la même façon.
    Hors j'ai besoin de classer les répertoires par ordre alphabétique et les fichiers par ordre croissant de taille.

    Merci quand même pour la réponse.

    Ps: Je ferai un copié/collé du petit script foireux que j'ai fait.

  4. #4
    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
    D'accord, je vois mieux ce dont il s'agit. Il est nécessaire de tout faire à la main puisque les critères sont assez peu standards (tri des répertoires par ordre alphabétique et des fichiers par taille). La récursivité est de mise. J'ai un premier jet qui semble fonctionner sur mon répertoire de musique (45GB de flac). La sortie n'est pas jolie, mais c'est une base de travail:
    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
    #!/bin/bash
     
    function listDir
    {
      # record current dir contents
      lineList=$(ls -l $dir | awk '
        BEGIN {OFS="/"}
        NR > 1 \
        {
          if (substr($1, 1, 1) == "d") {print "d", $NF}
          else {print $5, $NF}
        }')
      local d f
      local -a dirArray fileArray
      for line in $lineList
      do
        if [[ ${line%/*} == d ]]
        then
          dirArray[d++]="${line#*/}"
        else
          fileArray[f++]="${line%/*}/$dir/${line#*/}"
        fi
      done
     
      # display current dir name and recursively call function
      for dirItem in ${dirArray[*]}
      do
        dir="$dir/$dirItem"
        echo $dir
        listDir "$dir"
        dir="${dir%/*}"
      done
     
      # sort and display files in current dir
      echo "${fileArray[*]}" | tr ' ' $'\n' | sort -t "/" -n -k 1,1
    }
     
    dir=$1
    listDir $dir
    Le programme, ce sont les deux lignes du bas qui appellent la fonction qui s'appelle elle-même pour chaque sous-répertoire rencontré.

    Et maintenant, ça convient mieux?

  5. #5
    Membre à l'essai
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut
    Citation Envoyé par jmelyn Voir le message
    D'accord, je vois mieux ce dont il s'agit. Il est nécessaire de tout faire à la main puisque les critères sont assez peu standards (tri des répertoires par ordre alphabétique et des fichiers par taille). La récursivité est de mise. J'ai un premier jet qui semble fonctionner sur mon répertoire de musique (45GB de flac). La sortie n'est pas jolie, mais c'est une base de travail:
    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
    #!/bin/bash
     
    function listDir
    {
      # record current dir contents
      lineList=$(ls -l $dir | awk '
        BEGIN {OFS="/"}
        NR > 1 \
        {
          if (substr($1, 1, 1) == "d") {print "d", $NF}
          else {print $5, $NF}
        }')
      local d f
      local -a dirArray fileArray
      for line in $lineList
      do
        if [[ ${line%/*} == d ]]
        then
          dirArray[d++]="${line#*/}"
        else
          fileArray[f++]="${line%/*}/$dir/${line#*/}"
        fi
      done
     
      # display current dir name and recursively call function
      for dirItem in ${dirArray[*]}
      do
        dir="$dir/$dirItem"
        echo $dir
        listDir "$dir"
        dir="${dir%/*}"
      done
     
      # sort and display files in current dir
      echo "${fileArray[*]}" | tr ' ' $'\n' | sort -t "/" -n -k 1,1
    }
     
    dir=$1
    listDir $dir
    Le programme, ce sont les deux lignes du bas qui appellent la fonction qui s'appelle elle-même pour chaque sous-répertoire rencontré.

    Et maintenant, ça convient mieux?
    Bonsoir,

    Impressionnant le code ! Je ne m'attendais pas du tout à un script aussi complexe. On est loin de ce que j'essayai de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
     
    result=(ls -al)
     
    while read line "$result"
    do
            if [ -d "$line" ]; then
                    ls -lrS | sed -e 1d | awk '{print $1,$2,$5,$6,$7,$8}' | sort > file.csv
            fi
    done
    Je suis débutant dans le shell et je ne sais vraiment pas comment m'y prendre.

    Voici ce que me retourne le tiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@xala-serv:/home/xala/Musique# ./test.sh
    /Kanka
    ls: ne peut accéder /Kanka: Aucun fichier ou dossier de ce type
     
    /plop
    ls: ne peut accéder /plop: Aucun fichier ou dossier de ce type
     
    167//result.csv
    639//xaladio
    748//test.sh
    Je ne sais pas si ça vient de moi ou du script mais apparemment ça ne fonctionne pas.
    Pour info, pour ce test sur ma machine, le script est dans le répertoire contenant deux autres répertoires pleins de fichiers divers.

    Merci
    Cdlt

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut
    Je viens tirer aussi les oreilles à jmelyn :
    il est rarement utile, et toujours périlleux* d'utiliser ls dans des scripts!!
    d'autant que Bash dispose du Développement des chemins, par exemple :affiche la taille et le chemin/nom des fichiers et répertoires du /home/$USER

    maintenant, reste la question de la profondeur que tu souhaites donner à ta recherche : doit-elle aller dans tous les sous-répertoires, ou seulement dans les sous-répertoires immédiats d'un répertoire donné ?

    * dans le sens d'acrobatique : ça contraint à des {manip,gestic}ulations surfaitatoires du code.

    pour ma part, ne considérant que les sous-répertoires immédiats :
    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
    #!/bin/bash
     
    auMoinsUnFichier() {
       item=$1
       if [ -f "$item" ]
       then #echo  "{dir##*/}"
    # affichage en gras du nom des répertoires
            echo -e "\e[01m${dir##*/}\e[m"
            for file in $@
            do [ -f "$file" ] && stat -c'%s %n' "$file"
            done | sort -n | sed 's/.*\/\([^/]*.*\)/\1/'
       else shift
            [ -n "$1" ] && auMoinsUnFichier "$@"
       fi
    }
     
    #[ -d ~/CSVs ] || mkdir ~/CSVs
    Dir="${1:-.}"
    for dir in $Dir/*
    do [ -d "$dir" ] && {
          auMoinsUnFichier $dir/*
       }
    done #> ~/CSVs/results.csv
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre à l'essai
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Je viens tirer aussi les oreilles à jmelyn :
    il est rarement utile, et toujours périlleux* d'utiliser ls dans des scripts!!
    d'autant que Bash dispose du Développement des chemins, par exemple :affiche la taille et le chemin/nom des fichiers et répertoires du /home/$USER

    maintenant, reste la question de la profondeur que tu souhaites donner à ta recherche : doit-elle aller dans tous les sous-répertoires, ou seulement dans les sous-répertoires immédiats d'un répertoire donné ?

    * dans le sens d'acrobatique : ça contraint à des {manip,gestic}ulations surfaitatoires du code.

    pour ma part, ne considérant que les sous-répertoires immédiats :
    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
    #!/bin/bash
     
    auMoinsUnFichier() {
       item=$1
       if [ -f "$item" ]
       then #echo  "{dir##*/}"
    # affichage en gras du nom des répertoires
            echo -e "\e[01m${dir##*/}\e[m"
            for file in $@
            do [ -f "$file" ] && stat -c'%s %n' "$file"
            done | sort -n | sed 's/.*\/\([^/]*.*\)/\1/'
       else shift
            [ -n "$1" ] && auMoinsUnFichier "$@"
       fi
    }
     
    #[ -d ~/CSVs ] || mkdir ~/CSVs
    Dir="${1:-.}"
    for dir in $Dir/*
    do [ -d "$dir" ] && {
          auMoinsUnFichier $dir/*
       }
    done #> ~/CSVs/results.csv
    Bonjour N_BaH,

    Nickel ton script retourne ce que je voulais. Le truc c'est qu'il ne me retourne pas le résultat dans le fichier results.csv mais vers stdout. Et il me manque des informations comme la taille, la date et heure de création des fichiers.

    Mais il quelque chose qui me gène c'est que le script est encore moins compréhensible pour moi que le précédent. Où pourrais je en apprendre plus sur le shell bash ?

    En tout cas merci à vous deux de vous être penché sur mon problème.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut
    Bonjour Xalades,

    Citation Envoyé par Xalades
    Le truc c'est qu'il ne me retourne pas le résultat dans le fichier results.csv mais vers stdout.
    C'est prévu, mais mis en commentaire; il faut également décommenter le 'echo' au-dessus du commentaire concernant la mise en gras, et commenter celui en dessous.
    Et il me manque des informations comme la taille, la date et heure de création des fichiers.
    À la vue de ton exemple de sortie désirée, ce nétait pas évident.
    Par contre, les systèmes *n?x ne conservent pas la date de création des fichiers.
    Il est possible d'accéder à trois dates :
    dernier accès
    dernière modification
    dernier changement

    Mais il quelque chose qui me gène c'est que le script est encore moins compréhensible pour moi que le précédent.
    Où pourrais je en apprendre plus sur le shell bash ?
    en lisant l'ABS, le manuel de référence et le man , ou devrais-je dire les manpages des commandes utilisées,
    en ayant une console ouverte en permanence pour y passer des commandes au lieu de jouer de la souris...
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Membre à l'essai
    Inscrit en
    Avril 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 5
    Par défaut
    en lisant l'ABS, le manuel de référence et le man , ou devrais-je dire les manpages des commandes utilisées,
    en ayant une console ouverte en permanence pour y passer des commandes au lieu de jouer de la souris...
    Salut N_BaH !

    Merci pour les liens, et pour info j'utilise mes machine via putty donc si je clic c'est pour faire des c/c entre mon windob et mes nux

    Sinon concernant le script voici comment je l'ai modifié:

    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
    #!/bin/bash
     
    FileSearch() {
       item=$0
       if [ -f "$item" ]
       then echo -e  "---${dir##*/}---"
            for file in $@
            do [ -f "$file" ] &&  ls -l "$file"
            done | sort -n | awk '{print $1 "," $2 "," $5 "," $6 "," $7 "," $8}'
       else shift
            [ -n "$0" ] && FileSearch "$@"
       fi
    }
     
    [ -d ~/CSVs ] || mkdir ~/CSVs
    Dir="${1:-.}"
    for dir in $Dir/*
    do [ -d "$dir" ] && {
         FileSearch $dir/*
        }
    done > ~/CSVs/db.csv
    Pour le moment ça me va, à voir avec le temps. Si tu as des modif ou remarques sur cette variante de ton script n'hésites pas à me le dire.

    En tout cas merci.

Discussions similaires

  1. script création auto imprimante Win
    Par Pymm dans le forum Administration
    Réponses: 1
    Dernier message: 12/09/2007, 11h45
  2. erreur sur script création de tables
    Par PickEpique dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 15/03/2007, 18h24
  3. Script Création de table plus chargement
    Par Poisson59 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 10/08/2006, 14h14
  4. [VBA-A]Création CSV
    Par Mad X dans le forum VBA Access
    Réponses: 11
    Dernier message: 17/03/2006, 17h40
  5. [Oracle] Script création Table, violation de contraintes
    Par boudou dans le forum Langage SQL
    Réponses: 2
    Dernier message: 21/02/2006, 13h47

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