web-dev-qa-db-fra.com

Comment puis-je lister uniquement les dossiers sans sous-dossiers dans un chemin donné?

Problème: j'ai structuré dir

├── kat11
│   ├── kat21
│   │   └── Dokument\ bez\ nazwy
│   └── kat22
│       ├── kat31
│       │   └── Dokument\ bez\ nazwy
│       └── kat32
│           └── Dokument\ bez\ nazwy
├── kat12
│   └── kat21
│       └── Dokument\ bez\ nazwy
├── kat13
│   └── Dokument\ bez\ nazwy
└── kat14
    └── Kat21
        └── Kat32
            └── Dokument\ bez\ nazwy

Je veux lister uniquement tous les dossiers enfants avec le chemin complet.

par exemple

1. /kat14/kat21/kat32/Dokument\ bez\ nazwy
2. /kat11/kat22/kat31/Dokument\ bez\ nazwy
3. /kat11/kat22/kat32/Dokument\ bez\ nazwy
4. /kat12/kat21/Dokument\ bez\ nazwy
3
Tejas

Un simple find devrait suffire:

find /path/to/dir -type d -empty

Par exemple:

$ tree foo
foo
├── 1
│   ├── 1
│   ├── 2
│   └── 3
├── 2
│   ├── 1
│   ├── 2
│   └── 3
└── 3
    ├── 1
    ├── 2
    └── 3

12 directories, 0 files
$ find foo -type d -empty
foo/2/2
foo/2/3
foo/2/1
foo/3/2
foo/3/3
foo/3/1
foo/1/2
foo/1/3
foo/1/1
$ touch foo/1/1/a foo/2/1/a foo/3/1/a 
$ find foo -type d -empty            
foo/2/2
foo/2/3
foo/3/2
foo/3/3
foo/1/2
foo/1/3

Si ces répertoires peuvent contenir des fichiers, alors ce serait mieux, mais coûteux:

find foo -type d -exec sh -c 'find "$0" -mindepth 1 -type d -printf z | grep -q z || printf "%s\n" "$0"' {} \;

Ce message de débordement de pile a une solution plutôt soignée:

find /path/to/dir -type d -links 2

Puisqu'un répertoire sans sous-répertoires a seulement deux liens en dur, un deux son parent et un à lui-même.

La question, formulée différemment, a déjà été posée sur Stack Overflow, Super User et Unix & Linux:

4
muru

Dans un petit script python:

 #!/usr/bin/env python3
import os
import sys

src = sys.argv[1]
for root, dirs, files in os.walk(src):
    for dr in dirs:
        directory = root+"/"+dr
        if len([sub for sub in os.listdir(directory) \
                if os.path.isdir(directory+"/"+sub)]) == 0:
            print(directory)

Pour l'utiliser

  • Copiez-le dans un fichier vide, enregistrez-le sous le nom count_empty.py
  • Exécutez-le avec le répertoire ciblé comme argument:

    python3 /path/to/count_empty.py '<source_directory>'
    

Comment ça fonctionne

  • python's os.walk() parcourt les répertoires et les sous-répertoires
  • La ligne

    if len([sub for sub in os.listdir(directory) if os.path.isdir(directory+"/"+sub)]) == 0:
    

    compte ensuite le nombre de sous-répertoires sur chacun d’eux. S'il s'agit de zéro (pas de sous-répertoires), le répertoire et son chemin sont imprimés.

Testez sur un simple dossier de paquet sur mon bureau:

$ '/home/jacob/Bureaublad/pscript_5.py' '/home/jacob/Bureaublad/0.5.3' 
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/manpages
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/miscellaneous
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/icon
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/code
/home/jacob/Bureaublad/0.5.3/nonotifs-0.5.3/debian/source
6
Jacob Vlijm