Trouver des répertoires vides UNIX
je dois trouver des répertoires vides pour une liste donnée de répertoires. Certains annuaires ont des répertoires à l'intérieur.
si les répertoires internes sont vides, je peux dire que le répertoire principal est vide, sinon il n'est pas vide.
Comment puis-je tester?
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
11 réponses
vérifiez si find <dir> -type f
affiche quelque chose, voici un exemple:
for dir in A B C; do
[ -z "`find $dir -type f`" ] && echo "$dir is empty"
done
Ça dépend un peu de ce que vous voulez faire avec les répertoires vides. J'utilise la commande ci-dessous quand je souhaite supprimer tous les répertoires vides dans un arbre, dire test
répertoire.
find test -depth -empty -delete
une chose à noter à propos de la commande ci-dessus est que il va également supprimer les fichiers vides , donc utilisez l'option - type d pour éviter cela.
find test -depth -type d -empty -delete
Drop -delete
pour voir les fichiers et répertoires appariés.
si votre définition d'un arbre de répertoire vide est qu'il ne contient pas de fichiers, alors vous pouvez coller quelque chose ensemble basé sur si find test -type f
retourne quelque chose.
find
est d'une grande utilité, et RTFM tôt et souvent pour vraiment comprendre combien il peut le faire :-)
find directory -mindepth 1 -type d -empty -delete
C'est la version que j'ai trouvée la plus intéressante. Si elle est exécutée à partir de l'intérieur de répertoire , elle 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 la suppression du répertoire lui-même s'il est vide.
find . -type d -empty
trouve et liste les répertoires vides et les sous-répertoires dans l'arborescence courante. Par exemple: liste résultante de dirs et de sous-dirs 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 énumérés. Cela fonctionne pour moi.
Juste trouver vide dirs
afin de trouver des répertoires vides (comme spécifié dans le titre de la question), la réponse de mosg est correcte:
find -type d -empty
mais -empty
peut ne pas être disponible sur les très anciennes versions find
(c'est le cas de HP-UX par exemple). Si c'est votre cas, consultez les techniques décrites dans la section ci-dessous Est un répertoire vide? .
Supprimer "dirs vides
C'est un peu délicat: Supposons qu'un répertoire MyDir
contient les 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 possible:
find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} +
sur older find
version la déclaration +
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 différentes techniques que je connais:
-
[ $(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
un 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 quefind -maxdepth 0
à l'aide de moins de caractères -
find -type d
imprime seulement 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
-
-
(( ${#files} ))
Cette astuce est 100%
bash
mais invoque (fraie) un sous-shell. L'idée est de Bruno de Fraine et améliorée par teambob 's commentaire. 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
Note: aucune différence entre un répertoire vide et un répertoire non existant (et même lorsque le chemin indiqué est un fichier).
-
[ $(ls -A your/dir) ]
cette astuce est inspirée de article de nixCraft posté en 2007. Andrew Taylor , a 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 une ligne bashism version:
[[ "$(ls -A your/dir)" ]] && echo "contains files" || echo "empty or ..."
Note:
ls
retourne$?=2
lorsque le répertoire n'existe pas. Mais pas de différence entre un fichier et un répertoire vide.
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/ | `-- file5 |-- dir4/ | |-- dirD/ | `-- file4 `-- dir5/ `-- dirE/ `-- dir_V/
Le résultat de l'exécution de cette fonction serait:
./dir1 ./dir5/dirE/dir_V ./dir5/dirE ./dir5 ./dir2/dirB ./dir2
qui manque /dir4/dirD
. Si vous déplacez l'appel récursif findempty "$dir"
après le fi
, la fonction inclure ce répertoire dans ses résultats.
et rmdir *
? Cette commande échouera sur les répertoires non vides.
j'ai créé une structure simple comme suit:
"151900920"
Le test/test3/file
contient de l'ordure de texte.
Délivrance find test -empty
renvoie " test/test2/test2.2
" en tant que seul répertoire vide.
une approche simple serait,
$ [ "$(ls -A /path/to/direcory)" ] && echo "not empty" || echo "its empty"
aussi,
if [ "$(ls -A /path/to/direcory)" ]; then
echo "its not empty"
else
echo "empty directory"