Je dois conserver tous les répertoires contenant des fichiers dans un sous-répertoire spécifique, mais supprimer tous les répertoires dans lesquels le sous-répertoire est vide.
Pour être plus précis voici l'image:
A
|
|--------123456
| |
| |----Recording
| |----a.txt
| |----b.txt
|
|
|--------635623
| |----Recording
| |
| |-------a.mp3
| |----a.txt
| |----b.txt
|
|
|--------123456
| |----Recording
| |----a.txt
| |----b.txt
Les sous-répertoires peuvent ou non contenir un fichier. Il me faut donc supprimer tout le répertoire, comme "312311" et "566532" et ne laisser que "453453" avec toutes les données qu'il contient. Bcoz contient un fichier dans le dossier "Enregistrement" qui est un répertoire spécifique pour moi.
J'ai vu beaucoup de messages, mais cela renvoie à de nombreux noms de fichiers spécifiques. Toute aide sera grandement appréciée car je dois le faire plusieurs fois par semaine.
Le script ci-dessous fera exactement ce que vous décrivez:
Cherche dans chaque dossier un dossier nommé "Enregistrement"
Dans une image:
A
|
|--------123456
| |
| |----Recording
| |----a.txt
| |----b.txt
|
|
|--------635623
| |----Recording
| |
| |-------a.mp3
| |----a.txt
| |----b.txt
|
|
|--------123456
| |----Recording
| |----a.txt
| |----b.txt
|
|--------Monkey.txt
aura pour résultat:
A
|
|
|--------635623
| |----Recording
| |
| |-------a.mp3
| |----a.txt
| |----b.txt
|
|
|--------Monkey.txt
#!/usr/bin/env python3
import os
import sys
import shutil
dr = sys.argv[1]
def path(*args):
return os.path.join(*args)
for d in os.listdir(dr):
try:
if not os.listdir(path(dr, d, "Recording")):
shutil.rmtree(path(dr,d))
except FileNotFoundError:
shutil.rmtree(path(dr,d))
except NotADirectoryError:
pass
delete_empty.py
Exécutez-le avec le répertoire (complet!) (Contenant vos sous-répertoires, A dans votre exemple) comme argument de la commande:
python3 /path/to/delete_empty.py /path/to/directory
C'est ça.
Envoi du contenu du dossier "A" au script,
os.listdir(dr)
listera ses sous-répertoires (et fichiers). Ensuite:
if not os.listdir(path(dr, d, "Recording"))
essayera de lister le contenu de chacun des (sous) dossiers, ce qui provoquera une erreur si l'élément est un fichier:
except NotADirectoryError
pass
ou si le dossier "Enregistrement" n'existe pas du tout:
FileNotFoundError
shutil.rmtree(path(dr,d))
Si le dossier "Enregistrement" existe et que est vide, le dossier supérieur est supprimé:
if not os.listdir(path(dr, d, "Recording")):
shutil.rmtree(path(dr,d))
De plus, comme demandé dans les commentaires, une version qui vérifie la présence de plusieurs sous-répertoires (noms).
Si le répertoire contient l'un quelconque des sous-répertoires répertoriés (non vides), le répertoire est conservé. Sinon, il sera supprimé.
delete_empty.py
Exécutez-le avec le répertoire (complet!) (Contenant vos sous-répertoires, A dans votre exemple) et les noms des sous-répertoires en tant qu'arguments de la commande:
python3 /path/to/delete_empty.py /path/to/directory <subdir1> <subdir2> <subdir3>
C'est ça.
#!/usr/bin/env python3
import shutil
import os
import sys
dr = sys.argv[1]; matches = sys.argv[2:]
def path(*args):
return os.path.join(*args)
for d in os.listdir(dr):
# delete directory *unless* either one of the listed subdirs has files
keep = False
# check for each of the listed subdirs(names)
for name in matches:
try:
if os.listdir(path(dr, d, name)):
keep = True
break
except NotADirectoryError:
# if the item is not a dir, no use for other names to check
keep = True
break
except FileNotFoundError:
# if the name (subdir) does not exist, check for the next
pass
if not keep:
# if there is no reason to keep --> delete
shutil.rmtree(path(dr,d))
Veuillez d'abord exécuter un répertoire de test pour vous assurer qu'il fait exactement ce que vous voulez.
Utiliser find
et xargs
:
find A -type d -name 'Recording' -empty -printf '%h\0' | xargs -0 echo rm -rf
(Supprimez la echo
une fois que vous êtes certain qu’elle identifie les bons répertoires). La partie printf '%h\0
imprime le répertoire parent (terminé par un octet nul) - à partir de man find
:
%h Leading directories of file's name (all but the last ele‐
ment). If the file name contains no slashes (since it is
in the current directory) the %h specifier expands to
".".
Ex .: donné
$ tree A
A
├── 312311
│ ├── a.txt
│ ├── b.txt
│ └── Recording
├── 453453
│ ├── a.txt
│ ├── b.txt
│ └── Recording
│ └── a.mp3
└── 566532
├── a.txt
├── b.txt
└── Recording
6 directories, 7 files
ensuite
$ find A -type d -name 'Recording' -empty -printf '%h\0' | xargs -0 rm -rf
$
$ tree A
A
└── 453453
├── a.txt
├── b.txt
└── Recording
└── a.mp3
2 directories, 3 files
Voici une solution plus simple de bash:
for d in */; do rmdir "$d/Recording" && rm -r "$d"; done
Cela fonctionne car rmdir
échouera si le répertoire n'est pas vide et &&
empêchera l'exécution de rm -r
à moins que rmdir
ne réussisse. Le glob */
s'assure que vous ne travaillez que sur les répertoires afin que les autres fichiers ne soient pas affectés.