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 POSIX Discussion :

Tester si un répertoire est quasiment vide


Sujet :

Shell et commandes POSIX

  1. #1
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    avril 2008
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : avril 2008
    Messages : 2 051
    Points : 5 699
    Points
    5 699
    Par défaut Tester si un répertoire est quasiment vide
    Bonjour, je suis en train de faire du ménage sur mon mac (mais ça pourrait très bien être une machine sous linux).
    Notamment, après avoir écrit des scripts qui suppriment ou déplacent des fichiers, je voudrais supprimer les répertoires qui sont "réellement vides" ou "quasiment vides".

    Un répertoire réellement vide est un répertoire ne contenant aucun fichier ou dossier visible, ni aucun fichier ou dossier invisible (exception faite de "." et "..", bien sûr) et peut donc être supprimé par la commande rmdir.

    Pour moi, un répertoire quasiment vide est un répertoire ne contenant rien d'autre qu'un fichier "quasiment inutile", comme .DS_Store (sous OS X).

    Attention: un répertoire ne contenant qu'un sous-répertoire comme .git, par exemple, n'est PAS considéré comme quasiment vide !

    Attention: je ne souhaite pas supprimer tous les fichiers .DS_Store (dont certains peuvent être utiles...)

    En cherchant sur internet, j'ai trouvé une solution à base de ls:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function dir_ls_empty_p() {
        local files
        files=$(ls -A "$1" | head -2) # pour éviter de générer une trop grande chaine s il y a plein de fichiers
        if test -z "$files"; then return 0; fi
        if test "$files" = ".DS_Store"; then return 0; fi
        return 1
    }
    que l'on peut "raccourcir" en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function dir_ls_empty_p() {
        local files
        files=$(ls -A "$1" | head -2)
        test -z "$files" && return 0
        test "$files" = ".DS_Store"
    }
    mais, bien sûr, N_BaH va probablement dire que ça ne marche pas si un petit malin s'amuse à créer un unique fichier comme .DS_Store\n (mais qui aurait une idée pareille ?):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mkdir "./empty-not-DS-ret"
    touch 'empty-not-DS-ret/.DS_Store    
    '
    dir_ls_empty_p "./empty-not-DS-ret" && echo '=> vide'
    => vide
    ou si on crée un fichier "return":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mkdir "./empty-not-ret"
    touch 'empty-not-ret/    
    '
    dir_ls_empty_p "./empty-not-ret" && echo '=> vide'
    => vide

    J'ai aussi trouvé une solution à base de find:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function dir_is_empty_p() {
        local files
        files=$(find "$1" -name '.DS_Store' -prune -o -mindepth 1 -maxdepth 1 -print -quit)
        if test -z "$files"; then return 0; fi
        return 1
    }
    que l'on peut "raccourcir" en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function dir_is_empty_p() {
        local files
        files=$(find "$1" -name '.DS_Store' -prune -o -mindepth 1 -maxdepth 1 -print -quit)
        test -z "$files"
    }
    et qui semble plus robuste, notamment pour les fichiers avec "return".

    J'ai quelques questions:
    1. Voyez-vous des bugs (cas mal traités) dans cette fonction ?
    2. Voyez-vous d'autres solutions ? (si possible compatibles avec zsh)
    3. Comment "étendre" cette fonction (ou une autre) pour une liste de noms de fichiers "inutiles" (soit dans une variable, soit dans un fichier) ?

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    11 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 11 430
    Points : 27 967
    Points
    27 967
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par jack-ft Voir le message
    Pour moi, un répertoire quasiment vide est un répertoire ne contenant rien d'autre qu'un fichier "quasiment inutile", comme .DS_Store (sous OS X).

    Attention: un répertoire ne contenant qu'un sous-répertoire comme .git, par exemple, n'est PAS considéré comme quasiment vide !

    Attention: je ne souhaite pas supprimer tous les fichiers .DS_Store (dont certains peuvent être utiles...)
    Super. C'est ce qu'au bureau on nomme la règle du "ça dépend" si évidente pour les chefs et si facile à traduire en algo...

    Citation Envoyé par jack-ft Voir le message
    Comment "étendre" cette fonction (ou une autre) pour une liste de noms de fichiers "inutiles" (soit dans une variable, soit dans un fichier) ?
    Pour les autres questions je vois pas mais pour celle-là c'est assez facile: tu écris une fonction "fileInList(f, xxx, yyy, zzz, ...)" qui renvoie vrai si le fichier "f" se trouve dans la liste qui suit. Et ensuite au lieu de tester if test "$files" = ".DS_Store" tu écris if fileInList("$files", ..., ..., ...).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

    Informations forums :
    Inscription : septembre 2005
    Messages : 5 078
    Points : 12 848
    Points
    12 848
    Par défaut
    Bonjour

    Bonne poilade.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ > 'tes
    > t.txt'
    $ ls tes  #suivi de [TAB]
    tes             test.csv        testip.txt      test.log        testnotes.bash  t.txt           
    $ ls tes*
     test.csv   testip.txt   test.log   testnotes.bash  'tes'$'\n''t.txt'
    $ ls -A tes*
     test.csv   testip.txt   test.log   testnotes.bash  'tes'$'\n''t.txt'
    $ ls -A tes*.txt | head -n 2
    testip.txt
    tes
    Notez que "ls" fait la bonne liste des fichiers, l'autocomplétion se plante et "head" se plante.
    Notez aussi l'espace qui commence certaines lignes de résultat de "ls". Bonne variabilité pour un script systématique.
    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    avril 2008
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : avril 2008
    Messages : 2 051
    Points : 5 699
    Points
    5 699
    Par défaut
    Donc, comme d'hab, vaut mieux abandonner le ls au profit du find...

    Et, en réponse à la question 3, pour une boucle sur une liste de fichiers "inutiles":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    uselessopt=''
    while read f
    do uselessopt="$uselessopt -name '$f' -prune -o"
    done < /path/to/list-of-useless-files.txt
     
    function dir_is_empty_p() {
        local files
        files=$(find "$1" $uselessopt -mindepth 1 -maxdepth 1 -print -quit) # sans guillemets pour une fois (parce qu'on sait pourquoi)
        test -z "$files"
    }

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

Discussions similaires

  1. tester si un répertoire est vide
    Par guefrachi dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 15/01/2018, 20h13
  2. tester si un répertoire est vide
    Par laurentSc dans le forum Langage
    Réponses: 3
    Dernier message: 24/01/2010, 11h32
  3. [Batch] comment tester qu'un répertoire est vide ?
    Par JiCeBe dans le forum Scripts/Batch
    Réponses: 6
    Dernier message: 19/08/2009, 00h08
  4. [C#] Tester si un répertoire est vide
    Par Johann7751 dans le forum C#
    Réponses: 10
    Dernier message: 03/07/2009, 15h42
  5. Tester si un répertoire est accessible
    Par Pascal Lob dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 22/01/2009, 13h26

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