web-dev-qa-db-fra.com

Recherche de répertoires vides UNIX

J'ai besoin de trouver des répertoires vides pour une liste donnée de répertoires. Certains répertoires contiennent des répertoires.

Si les répertoires internes sont également vides, je peux dire que le répertoire principal est vide sinon il n'est pas vide.

Comment puis-je tester cela?

Par exemple:

A>A1(file1),A2 this is not empty beacuse of file1
B>B1(no file) this is empty
C>C1,C2 this is empty
88
soField

Vérifier si find <dir> -type f affiche n'importe quoi, voici un exemple:

for dir in A B C; do
    [ -z "`find $dir -type f`" ] && echo "$dir is empty"
done
33
Marcelo Cantos

Cela dépend un peu de ce que vous voulez faire avec les répertoires vides. J'utilise la commande ci-dessous lorsque je souhaite supprimer tous les répertoires vides dans une arborescence, par exemple test répertoire.

find test -depth -empty -delete

Une chose à noter à propos de la commande ci-dessus est que elle supprimera également les fichiers vides, utilisez donc l'option - tapez d pour éviter ça.

find test -depth -type d -empty -delete

Laissez tomber -delete pour voir les fichiers et répertoires correspondants.

Si votre définition d'une arborescence de répertoires vide est qu'elle ne contient aucun fichier, vous pouvez coller quelque chose ensemble selon que find test -type f renvoie n'importe quoi.

find est un excellent utilitaire, et RTFM tôt et souvent pour vraiment comprendre ce qu'il peut faire :-)

244
Martin

Vous pouvez utiliser la commande suivante:

find . -type d -empty
41
mosg
find directory -mindepth 1 -type d -empty -delete

C'est la version que j'ai trouvée la plus intéressante. S'il est exécuté de l'intérieur répertoire, il supprimera tous les répertoires vides ci-dessous (un répertoire est considéré comme vide s'il ne contient que des répertoires vides).

L'option mindepth empêche le répertoire lui-même d'être supprimé s'il se trouve être vide.

25

find . -type d -empty

recherche et répertorie les répertoires et sous-répertoires vides dans l'arborescence actuelle. Par exemple. liste résultante de répertoires et sous-répertoires vides:

./2047
./2032
./2049
./2063
./NRCP26LUCcct1/2039
./NRCP26LUCcct1/2054
./NRCP26LUCcct1/2075
./NRCP26LUCcct1/2070

Aucune opération n'est effectuée sur les répertoires. Ils sont simplement répertoriés. Cela fonctionne pour moi.

22
user7194913

Il suffit de trouver des répertoires vides

Afin de trouver simplement des répertoires vides (comme spécifié dans le titre de la question), le réponse de mosg est correct:

find -type d -empty

Mais -empty Peut ne pas être disponible sur les très anciennes versions de find (c'est le cas de HP-UX par exemple). Si tel est votre cas, consultez les techniques décrites dans la section ci-dessous Un répertoire est-il vide?.

Supprimer les répertoires vides

C'est un peu délicat: supposons qu'un répertoire MyDir contienne des répertoires vides. Après avoir supprimé ces répertoires vides, MyDir deviendra un répertoire vide et devrait également être supprimé. Par conséquent, j'utilise la commande rmdir avec l'option --parents (Ou -p) Qui supprime également les répertoires parents lorsque cela est possible:

find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} +

Sur les anciennes versions de find, l'instruction + N'est pas encore prise en charge, vous pouvez donc utiliser ; À la place:

find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} `;`

Un répertoire est-il vide?

La plupart de ces réponses expliquent comment vérifier si un répertoire est vide. Par conséquent, je fournis ici les trois techniques différentes que je connais:

  1. [ $(find your/dir -Prune -empty) = your/dir ]

    d=your/dir
    if [ x$(find "$d" -Prune -empty) = x"$d" ]
    then
      echo "empty (directory or file)"
    else
      echo "contains files (or does not exist)"
    fi
    

    une variation:

    d=your/dir
    if [ x$(find "$d" -Prune -empty -type d) = x"$d" ]
    then
      echo "empty directory"
    else
      echo "contains files (or does not exist or is not a directory)"
    fi
    

    Explication:

    • find -Prune Est similaire à find -maxdepth 0 En utilisant moins de caractères
    • find -type d Imprime uniquement les répertoires
    • find -empty Imprime les répertoires et fichiers vides

      > mkdir -v empty1 empty2 not_empty
      mkdir: created directory 'empty1'
      mkdir: created directory 'empty2'
      mkdir: created directory 'not_empty'
      > touch not_empty/file
      > find empty1 empty2 not_empty -Prune -empty
      empty1
      empty2
      
  2. (( ${#files} ))

    Cette astuce est à 100% bash mais invoque (fait apparaître) un sous-shell. L'idée est de Bruno De Fraine et améliorée par le commentaire de teambob . Je conseille celui-ci si vous utilisez bash et si votre script ne doit pas être portable.

    files=$(shopt -s nullglob dotglob; echo your/dir/*)
    if (( ${#files} ))
    then 
      echo "contains files"
    else 
      echo "empty (or does not exist or is a file)"
    fi
    

    Remarque: aucune différence entre un répertoire vide et un répertoire inexistant (et même lorsque le chemin fourni est un fichier).

  3. [ $(ls -A your/dir) ]

    Cette astuce est inspirée de article de nixCraft publié en 2007. Andrew Taylor répondu en 2008 et gr8can8dian en 2011.

    if [ "$(ls -A your/dir)" ]
    then
      echo "contains files"
    else
      echo "empty (or does not exist or is a file)"
    fi
    

    ou la version bashisme à une ligne:

    [[ "$(ls -A your/dir)" ]] && echo "contains files" || echo "empty or ..."
    

    Remarque: ls renvoie $?=2 Lorsque le répertoire n'existe pas. Mais aucune différence entre un fichier et un répertoire vide.

16
olibre

Cette fonction récursive semble faire l'affaire:

# Bash
findempty() {
    find ${1:-.} -mindepth 1 -maxdepth 1 -type d | while read -r dir
    do
        if [[ -z "$(find "$dir" -mindepth 1 -type f)" ]] >/dev/null
        then
            findempty "$dir"
            echo "$dir"
        fi
    done
}

Étant donné cet exemple de structure de répertoire:

. 
 | - dir1 /
 | - dir2 /
 | `- dirB /
 | - dir3 /
 | `- dirC /
 | `- fichier5 
 | - dir4 /
 | | - dirD /
 | `- fichier4 
` - dir5 /
 `- dirE /
` - dir_V /

Le résultat de l'exécution de cette fonction serait:

. ____.] ./dir2

qui manque /dir4/dirD. Si vous déplacez l'appel récursif findempty "$dir" après le fi, la fonction inclura ce répertoire dans ses résultats.

2

Que diriez-vous rmdir *? Cette commande échouera sur les répertoires non vides.

1
evandrix

J'ai créé une structure simple comme suit:


test/
test/test2/
test/test2/test2.2/
test/test3/
test/test3/file

Le test/test3/file contient du texte indésirable.

Émission find test -empty résultats "test/test2/test2.2 "comme seul répertoire vide.

0
James Sumners

une approche simple serait,

$ [ "$(ls -A /path/to/direcory)" ] && echo "not empty" || echo "its empty"

également,

if [ "$(ls -A /path/to/direcory)" ]; then
   echo "its not empty"
else 
   echo "empty directory"
0
phoenix24
find . -name -type d -ls |awk '($2==0){print $11}'
0
Vijay