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
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
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 :-)
Vous pouvez utiliser la commande suivante:
find . -type d -empty
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.
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.
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?.
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 {} `;`
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:
[ $(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èresfind -type d
Imprime uniquement les répertoiresfind -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 (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).
[ $(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.
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.
Que diriez-vous rmdir *
? Cette commande échouera sur les répertoires non vides.
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.
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"
find . -name -type d -ls |awk '($2==0){print $11}'