Vérification à partir du script shell si un répertoire contient des fichiers


116

À partir d'un script shell, comment vérifier si un répertoire contient des fichiers?

Quelque chose de semblable à ça

if [ -e /some/dir/* ]; then echo "huzzah"; fi;

mais qui fonctionne si le répertoire contient un ou plusieurs fichiers (celui ci-dessus ne fonctionne qu'avec exactement 0 ou 1 fichiers).


Pour ce que ça vaut votre exemple, bon fait ce que vous voulez dans ksh et zsh
Dave Webb

2
@DaveWebb Non, ce n'est pas le cas. Si le glob se développe à plus d'un mot, le test zsh signale «test: trop d'arguments».
Jens

"huzzah" signifie "le répertoire n'est pas vide".
funroll

Si le répertoire ne contient qu'un sous-répertoire vide, cela compte-t-il comme "contenant des fichiers"?
Keith Thompson

Réponses:


72

Les solutions utilisées jusqu'ici ls. Voici une solution tout bash:

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi

8
tant que vous vous souvenez de remettre les options à leur valeur d'origine à la fin du script :)
Jean

Il s'agit d'une version légèrement améliorée qui prend en charge la réinitialisation des paramètres de bash:shopt -q nullglob || resetnullglob=1; shopt -s nullglob; shopt -q dotglob || resetdotglob=1; shopt -s dotglob; files=(/some/dir/*); [ "$files" ] && echo "wowzers"; [ "$resetdotglob" ] && shopt -u dotglob; [ "$resetnullglob" ] && shopt -u nullglob;
user123444555621

12
Pourquoi ne pas utiliser un sous-shell pour réinitialiser les paramètres:files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*)
teambob

7
@teambob si vous utilisez un sous-shell: files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*) alors l'instruction if devrait changer en if [ ${#files} -gt 0 ];ou peut-être avez-vous simplement oublié le () autour de la commande du sous-shell? files=($(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*))
stoutyhk

2
@stoutyhk $ (...) restaure les paramètres, aucun sous-shell séparé n'est requis. L'utilisation de $ (...) génère une nouvelle instance du shell. L'environnement de cette nouvelle instance est jeté une fois la commande terminée. Edit: On a trouvé une référence tldp.org/LDP/abs/html/commandsub.html "La substitution de commande appelle un sous-shell."
teambob

140

Trois meilleurs trucs


shopt -s nullglob dotglob; f=your/dir/*; ((${#f}))

Cette astuce est à 100% bashet invoque (génère) un sous-shell. L'idée est de Bruno De Fraine et améliorée par le commentaire de teambob .

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: pas de différence entre un répertoire vide et un répertoire inexistant (et même lorsque le chemin fourni est un fichier).

Il existe une alternative similaire et plus de détails (et plus d'exemples) sur la FAQ `` officielle '' du canal IRC #bash :

if (shopt -s nullglob dotglob; f=(*); ((${#f[@]})))
then
  echo "contains files"
else 
  echo "empty (or does not exist, or is a file)"
fi

[ -n "$(ls -A your/dir)" ]

Cette astuce est inspirée de l'article de nixCraft publié en 2007. Ajoutez 2>/dev/nullpour supprimer l'erreur de sortie "No such file or directory".
Voir aussi la réponse d' Andrew Taylor (2008) et la réponse de gr8can8dian (2011).

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

ou la version bashisme en une ligne:

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

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


[ -n "$(find your/dir -prune -empty)" ]

Cette dernière astuce est inspirée de la réponse de gravstar-maxdepth 0est remplacé -pruneet amélioré par le commentaire de phils .

if [ -n "$(find your/dir -prune -empty 2>/dev/null)" ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

une variante utilisant -type d:

if [ -n "$(find your/dir -prune -empty -type d 2>/dev/null)" ]
then
  echo "empty directory"
else
  echo "contains files (or does not exist or is not a directory)"
fi

Explication:

  • find -pruneest similaire à l' find -maxdepth 0utilisation de moins de caractères
  • find -empty imprime les répertoires et fichiers vides
  • find -type d imprime uniquement les répertoires

Remarque: vous pouvez également remplacer [ -n "$(find your/dir -prune -empty)" ]uniquement par la version raccourcie ci-dessous:

if [ `find your/dir -prune -empty 2>/dev/null` ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

Ce dernier code fonctionne dans la plupart des cas mais sachez que des chemins malveillants pourraient exprimer une commande ...


2
Je pense que vous pouvez simplifier l'option de recherche [ -n "$(find "your/dir" -prune -empty)" ]pour éviter la répétition du chemin du répertoire.
phils

Lors de l'utilisation if [ ``ls -A your/dir`` ]dans un script, je suis arrivé à la conclusion que cela fonctionne bien pour un répertoire avec 0, 1 ou 2 sous-répertoires, mais échoue pour un répertoire avec plus de 2 sous-répertoires. line 17: [: 20150424-002813: unary operator expected20150424-002813était l'un des noms de répertoire. La coquille utilisée était /bin/bash/. Je l'ai finalement changé enls "$destination" | tail -1
Christophe De Troyer

Salut @ChristopheDeTroyer Je ne peux pas reproduire votre problème. De mon côté if [ ``ls -A my/dir`` ]sort par erreur bash: [: -A: binary operator expected. Testé sur les versions bash 4.1.2 et 4.2.53.
olibre

1
Eh bien, j'étais principalement motivé à commenter en raison de l'incohérence perçue (puisque la -nvariante était dans le titre mais pas dans le paragraphe ci-dessous). Alors, oui, ça va.
maxschlepzig

1
J'utilise votre solution -n, mon script se plaint toujours de cela ls: cannot access '/path': No such file or directory. Existe-t-il un moyen de supprimer ce message? Je voudrais y échouer en silence.
Freedo

48

Que diriez-vous de ce qui suit:

if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

De cette façon, il n'est pas nécessaire de générer une liste complète du contenu du répertoire. Le readest à la fois de rejeter la sortie et de rendre l'expression évaluée à vrai uniquement lorsque quelque chose est lu (c'est /some/dir/-à- dire trouvé vide par find).


3
ou simplementfind /some/dir/ -maxdepth 0 -empty -exec echo "huzzah" \;
doubleDown

5
+1 C'est la solution la plus élégante. Il n'implique pas l'analyse de la lssortie et ne repose pas sur des fonctionnalités de shell non par défaut.

7
Il repose cependant sur les non-standards -maxdepthet les -emptyprimaires.
chepner

21

Essayer:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi

Cela a fonctionné pour moi, mais je ne peux pas formater ce message d * mn !!! <br> export tmp = /bin/ls <some_dir>/* 2> /dev/nullsi [! -z "$ tmp"]; puis echo Quelque chose est là fi
AndrewStone

1
Pour les idiots de Bash comme moi, si vous voulez vérifier le contraire - que le répertoire est vide - utilisez simplement if [-z ls /some/dir/*]; puis echo "huzzah"; fi
Chris Moschini

4
Vous pouvez utiliser à la -nplace de ! -z(ils sont tous les deux équivalents, mais pourquoi ne pas utiliser la forme la plus courte lorsqu'elle existe).
n

Avec ZSH, cet exemple génère une erreur, l'idée est de ne pas avoir l'erreur renvoyée ... BigGray% if [ ! -z ls / some / dir / * `]; puis echo "huzzah"; fi zsh: aucune correspondance trouvée: / some / dir / * `
Hvisage

ne fonctionne pas pour moi sans guillemets ls...dans bash
letmutx

15
# Works on hidden files, directories and regular files
### isEmpty()
# This function takes one parameter:
# $1 is the directory to check
# Echoes "huzzah" if the directory has files
function isEmpty(){
  if [ "$(ls -A $1)" ]; then
    echo "huzzah"
  else 
    echo "has no files"
  fi
}

15

Faites attention aux répertoires contenant beaucoup de fichiers! L'évaluation de la lscommande peut prendre un certain temps .

IMO la meilleure solution est celle qui utilise

find /some/dir/ -maxdepth 0 -empty

8
DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi

6

Pourriez-vous comparer la sortie de ceci?

 ls -A /some/dir | wc -l

4
# Vérifie si un répertoire contient des fichiers non cachés.
#
# utilisation: si est vide "$ HOME"; puis echo "Bienvenue à la maison"; Fi
#
est vide() {
    pour _ief dans $ 1 / *; faire
        if [-e "$ _ief"]; puis
            retour 1
        Fi
    terminé
    retourne 0
}

Quelques notes de mise en œuvre:

  • La forboucle évite un appel à un lsprocessus externe . Il lit toujours toutes les entrées du répertoire une fois. Cela ne peut être optimisé qu'en écrivant un programme C qui utilise explicitement readdir ().
  • L' test -eintérieur de la boucle attrape le cas d'un répertoire vide, auquel cas la variable se _iefverrait attribuer la valeur "somedir / *". Ce n'est que si ce fichier existe que la fonction retournera "non vide"
  • Cette fonction fonctionnera dans toutes les implémentations POSIX. Mais sachez que Solaris / bin / sh n'entre pas dans cette catégorie. Son testimplémentation ne prend pas en charge le -edrapeau.

1
Cela ignorerait les fichiers dot dans le répertoire s'il dotglobn'est pas défini -shopt -s dotglob
l0b0

4

Cela me dit si le répertoire est vide ou si ce n'est pas le cas, le nombre de fichiers qu'il contient.

directory="/some/dir"
number_of_files=$(ls -A $directory | wc -l)

if [ "$number_of_files" == "0" ]; then
    echo "directory $directory is empty"
else
    echo "directory $directory contains $number_of_files files"
fi

Quelqu'un peut-il m'expliquer pourquoi j'ai été rejeté? Si j'écris au craps, j'aimerais savoir pourquoi;)
Daishi

1
Je n'ai pas voté contre cela, mais je suppose que c'est parce que vous analysez la sortie dels .
Toby Speight

l'article lié n'est-il pas clair? Si tel est le cas, envoyez un e-mail à l'auteur (pas à moi).
Toby Speight

1
@TobySpeight Je vois le point. Mais dans ce cas, je compte les lignes sans les énumérer. Il ne doit donner un résultat faux que si un nom de fichier contient une nouvelle ligne. Et si les noms de fichiers contiennent de nouvelles lignes, quelque chose de beaucoup plus important doit avoir f ** ked quelque part;)
Daishi

3

Cela peut être une réponse très tardive, mais voici une solution qui fonctionne. Cette ligne ne reconnaît que l'existence de fichiers! Cela ne vous donnera pas de faux positif si des répertoires existent.

if find /path/to/check/* -maxdepth 0 -type f | read
  then echo "Files Exist"
fi

2
dir_is_empty() {
   [ "${1##*/}" = "*" ]
}

if dir_is_empty /some/dir/* ; then
   echo "huzzah"
fi

Supposons que vous ne disposez pas d'un fichier nommé *dans /any/dir/you/check, il doit travailler bash dash posh busybox shet zshmais (pour zsh) exigent unsetopt nomatch.

Les performances devraient être comparables à celles lsqui utilisent *(glob), je suppose que ce sera lent sur les répertoires avec de nombreux nœuds (mon /usr/binavec plus de 3000 fichiers n'est pas si lent), utilisera au moins assez de mémoire pour allouer tous les répertoires / noms de fichiers (et plus) comme ils sont tous passés (résolus) à la fonction en tant qu'arguments, certains shell ont probablement des limites sur le nombre d'arguments et / ou la longueur des arguments.

Un moyen portable rapide O (1) zéro ressources pour vérifier si un répertoire est vide serait bien d'avoir.

mettre à jour

La version ci-dessus ne tient pas compte des fichiers / répertoires cachés, au cas où des tests supplémentaires seraient nécessaires, comme les astucesis_empty de Rich's sh (shell POSIX) :

is_empty () (
cd "$1"
set -- .[!.]* ; test -f "$1" && return 1
set -- ..?* ; test -f "$1" && return 1
set -- * ; test -f "$1" && return 1
return 0 )

Mais, à la place, je pense à quelque chose comme ça:

dir_is_empty() {
    [ "$(find "$1" -name "?*" | dd bs=$((${#1}+3)) count=1 2>/dev/null)" = "$1" ]
}

Une certaine inquiétude concernant les différences de barres obliques de fin par rapport à l'argument et la sortie de recherche lorsque le répertoire est vide, et les nouvelles lignes de fin (mais cela devrait être facile à gérer), malheureusement, dans mon busybox shémission, ce qui est probablement un bogue sur le find -> ddtube avec la sortie tronquée de manière aléatoire ( si j'ai utilisé catla sortie est toujours la même, semble être ddavec l'argument count).


J'adore la solution portable. Je suis venu donner la même réponse. Je venais de l'écrire différemment (retournez 2 sinon un répertoire). De plus, ces solutions portables ont l'avantage de ne pas appeler de programmes externes, ce qui peut être un plus pour les systèmes contraints ou embarqués. Je crains seulement que l'utilisation de "()" puisse créer un nouveau sous-processus (ou au moins obliger à copier l'environnement et les choses, puis revenir en arrière). Jetez un œil à ceci: is_empty () {_d = "$ {1: -.}"; [! -d "$ {_ d}"] && return 2; set - "$ {_ d}" / * "$ {_ d}" /.[!.... .* "$ {_ d}" /..?*; ["$ { }" = "$ {_ d} / $ {_ d} /. [!.] * $ {_ d} /..?*"]; };
Diego Augusto Molina

@DiegoAugustoMolina Récemment dans un projet, j'ai dû refaire ce test, si un répertoire était vide, au début j'utilisais python, puis comme j'ai pratiquement installé python juste pour ça, j'ai implémenté le test en c, l'implémentation est d'une extrême banalité, je me demande pourquoi il n'a jamais été ajouté comme test ou comme commande autonome
Alex

1
J'ai aussi eu récemment besoin d'une solution à ce problème pour un système (vraiment) contraint. J'ai même optimisé un peu le code précédent pour n'utiliser aucune variable supplémentaire. Un doublage hackish et laid mais génial. Servez-vous:is_empty(){ [ ! -d "${1}" ] && return 2;set -- "${1}" "${1}"/* "${1}"/.[!.]* "${1}"/..?*;[ "${*}" = "${1} ${1}/* ${1}/.[!.]* ${1}/..?*" ]; };
Diego Augusto Molina

2

ZSH

Je sais que la question a été marquée pour bash; mais, juste pour référence, pour les utilisateurs zsh :

Tester le répertoire non vide

Pour vérifier si ce foon'est pas vide:

$ for i in foo(NF) ; do ... ; done

où, si foon'est pas vide, le code du forbloc sera exécuté.

Tester le répertoire vide

Pour vérifier si fooest vide:

$ for i in foo(N/^F) ; do ... ; done

où, si fooest vide, le code du forbloc sera exécuté.

Remarques

Nous n'avons pas eu besoin de citer le répertoire fooci-dessus, mais nous pouvons le faire si nous devons:

$ for i in 'some directory!'(NF) ; do ... ; done

Nous pouvons également tester plus d'un objet, même s'il ne s'agit pas d'un répertoire:

$ mkdir X     # empty directory
$ touch f     # regular file
$ for i in X(N/^F) f(N/^F) ; do echo $i ; done  # echo empty directories
X

Tout ce qui n'est pas un répertoire sera simplement ignoré.

Suppléments

Puisque nous sommes en train de globbing, nous pouvons utiliser n'importe quel glob (ou extension d'accolades):

$ mkdir X X1 X2 Y Y1 Y2 Z
$ touch Xf                    # create regular file
$ touch X1/f                  # directory X1 is not empty
$ touch Y1/.f                 # directory Y1 is not empty
$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ for i in {X,Y}*(N/^F); do printf "$i "; done; echo  # print empty directories
X X2 Y Y2

Nous pouvons également examiner les objets placés dans un tableau. Avec les répertoires comme ci-dessus, par exemple:

$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ arr=(*)                     # place objects into array "arr"
$ for i in ${^arr}(N/^F); do printf "$i "; done; echo
X X2 Y Y2 Z

Ainsi, nous pouvons tester des objets qui peuvent déjà être définis dans un paramètre de tableau.

Notez que le code dans le forbloc est, évidemment, exécuté sur chaque répertoire à tour de rôle. Si cela n'est pas souhaitable, vous pouvez simplement renseigner un paramètre de tableau, puis opérer sur ce paramètre:

$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories

Explication

Pour les utilisateurs de zsh, il y a le (F)qualificatif glob (voir man zshexpn), qui correspond aux répertoires "pleins" (non vides):

$ mkdir X Y
$ touch Y/.f        # Y is now not empty
$ touch f           # create a regular file
$ ls -dF *          # list everything in the current directory
f X/ Y/
$ ls -dF *(F)       # will list only "full" directories
Y/

Le qualificatif (F)répertorie les objets qui correspondent: est un répertoire ET n'est pas vide. Donc, (^F)correspond: pas un répertoire OU est vide. Ainsi, (^F)seul listerait également les fichiers réguliers, par exemple. Ainsi, comme expliqué sur la zshexppage de manuel, nous avons également besoin du (/)qualificatif glob, qui répertorie uniquement les répertoires:

$ mkdir X Y Z
$ touch X/f Y/.f    # directories X and Y now not empty
$ for i in *(/^F) ; do echo $i ; done
Z

Ainsi, pour vérifier si un répertoire donné est vide, vous pouvez donc lancer:

$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished

et juste pour être sûr qu'un répertoire non vide ne serait pas capturé:

$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished

Oups! Puisqu'il Yn'est pas vide, zsh ne trouve aucune correspondance pour (/^F)("répertoires qui sont vides") et crache donc un message d'erreur indiquant qu'aucune correspondance pour le glob n'a été trouvée. Nous devons donc supprimer ces éventuels messages d'erreur avec le (N)qualificatif glob:

$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished

Ainsi, pour les répertoires vides, nous avons besoin du qualificatif (N/^F), que vous pouvez lire comme: "ne me prévenez pas des pannes, des répertoires qui ne sont pas pleins".

De même, pour les répertoires non vides, nous avons besoin du qualificatif (NF), que nous pouvons également lire comme: "ne me prévenez pas des pannes, répertoires complets".


1

Je suis surpris que le guide Wooledge sur les répertoires vides n'ait pas été mentionné. Ce guide, et tout le Wooledge vraiment, est une lecture incontournable pour les questions de type coquille.

À noter sur cette page:

N'essayez jamais d'analyser la sortie de ls. Même les solutions ls -A peuvent casser (par exemple sur HP-UX, si vous êtes root, ls -A fait exactement le contraire de ce qu'il fait si vous n'êtes pas root - et non, je ne peux pas inventer quelque chose d'aussi incroyable stupide).

En fait, on peut souhaiter éviter complètement la question directe. Habituellement, les gens veulent savoir si un répertoire est vide parce qu'ils veulent faire quelque chose impliquant les fichiers qu'il contient, etc. Regardez la question plus large. Par exemple, l'un de ces exemples basés sur la recherche peut être une solution appropriée:

   # Bourne
   find "$somedir" -type f -exec echo Found unexpected file {} \;
   find "$somedir" -maxdepth 0 -empty -exec echo {} is empty. \;  # GNU/BSD
   find "$somedir" -type d -empty -exec cp /my/configfile {} \;   # GNU/BSD

Le plus souvent, tout ce dont vous avez vraiment besoin est quelque chose comme ceci:

   # Bourne
   for f in ./*.mpg; do
        test -f "$f" || continue
        mympgviewer "$f"
    done

En d'autres termes, la personne qui pose la question peut avoir pensé qu'un test de répertoire vide explicite était nécessaire pour éviter un message d'erreur comme mympgviewer: ./*.mpg: Aucun fichier ou répertoire de ce type alors qu'en fait aucun test de ce type n'est requis.


1

Petite variation de la réponse de Bruno :

files=$(ls -1 /some/dir| wc -l)
if [ $files -gt 0 ] 
then
    echo "Contains files"
else
    echo "Empty"
fi

Ça marche pour moi


1

Prenant un indice (ou plusieurs) de la réponse d'Olibre, j'aime une fonction Bash:

function isEmptyDir {
  [ -d $1 -a -n "$( find $1 -prune -empty 2>/dev/null )" ]
}

Parce que bien qu'il crée un sous-shell, il est aussi proche d'une solution O (1) que je peux l'imaginer et lui donner un nom le rend lisible. Je peux alors écrire

if isEmptyDir somedir
then
  echo somedir is an empty directory
else
  echo somedir does not exist, is not a dir, is unreadable, or is  not empty
fi

En ce qui concerne O (1), il existe des cas aberrants: si un grand répertoire a eu tout ou tout, sauf la dernière entrée supprimée, «find» peut devoir lire le tout pour déterminer s'il est vide. Je crois que les performances attendues sont O (1) mais le pire des cas est linéaire dans la taille du répertoire. Je n'ai pas mesuré cela.


0

Jusqu'à présent, je n'ai pas vu de réponse utilisant grep qui, je pense, donnerait une réponse plus simple (avec pas trop de symboles étranges!). Voici comment je vérifierais si des fichiers existent dans le répertoire en utilisant bourne shell:

ceci renvoie le nombre de fichiers dans un répertoire:

ls -l <directory> | egrep -c "^-"

vous pouvez remplir le chemin du répertoire dans lequel le répertoire est écrit. La première moitié du tube garantit que le premier caractère de sortie est "-" pour chaque fichier. egrep compte ensuite le nombre de lignes commençant par ce symbole à l'aide d'expressions régulières. maintenant, tout ce que vous avez à faire est de stocker le numéro que vous obtenez et de le comparer en utilisant des guillemets comme:

 #!/bin/sh 
 fileNum=`ls -l <directory> | egrep -c "^-"`  
 if [ $fileNum == x ] 
 then  
 #do what you want to do
 fi

x est une variable de votre choix.


0

Mélanger les choses de pruneau et les dernières réponses, je suis arrivé à

find "$some_dir" -prune -empty -type d | read && echo empty || echo "not empty"

qui fonctionne aussi pour les chemins avec des espaces



0

J'irais pour find:

if [ -z "$(find $dir -maxdepth 1 -type f)" ]; then
    echo "$dir has NO files"
else
    echo "$dir has files"

Cela vérifie le résultat de la recherche de fichiers uniquement dans le répertoire, sans passer par les sous-répertoires. Ensuite, il vérifie la sortie en utilisant l' -zoption tirée de man test:

   -z STRING
          the length of STRING is zero

Voir quelques résultats:

$ mkdir aaa
$ dir="aaa"

Rép vide:

$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

Juste dirs dedans:

$ mkdir aaa/bbb
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

Un fichier dans le répertoire:

$ touch aaa/myfile
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
$ rm aaa/myfile 

Un fichier dans un sous-répertoire:

$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

0

Avec une solution de contournement, je pourrais trouver un moyen simple de savoir s'il y a des fichiers dans un répertoire. Cela peut s'étendre avec d'autres commandes grep pour vérifier spécifiquement les fichiers .xml ou .txt, etc. Ex:ls /some/dir | grep xml | wc -l | grep -w "0"

#!/bin/bash
if ([ $(ls /some/dir | wc -l  | grep -w "0") ])
    then
        echo 'No files'
    else
        echo 'Found files'
fi

-1
if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;

J'aime celui-ci car il n'y a pas de guillemets ou de crochets pour la commande.
Dave Webb

Attention à ne pas l'utiliser si vous définissez nullglob, car la lscommande réussira.
Steve Kehlet

Ne fonctionnera pas dans tous les environnements au cas où le répertoire contiendrait des fichiers dot.
Diego Augusto Molina

-1

pour tester un répertoire cible spécifique

if [ -d $target_dir ]; then
    ls_contents=$(ls -1 $target_dir | xargs); 
    if [ ! -z "$ls_contents" -a "$ls_contents" != "" ]; then
        echo "is not empty";
    else
        echo "is empty";
    fi;
else
    echo "directory does not exist";
fi;

-1

Essayez avec la commande find. Spécifiez le répertoire codé en dur ou comme argument. Ensuite, lancez la recherche pour rechercher tous les fichiers dans le répertoire. Vérifiez si le retour de la recherche est nul. Faire écho aux données de trouver

#!/bin/bash

_DIR="/home/user/test/"
#_DIR=$1
_FIND=$(find $_DIR -type f )
if [ -n "$_FIND" ]
then
   echo -e "$_DIR contains files or subdirs with files \n\n "
   echo "$_FIND"
else
echo "empty (or does not exist)"
fi

Si le répertoire contient des répertoires vides ou des fichiers non réguliers (sockets, périphériques char, liens symboliques, etc.), cela ne fonctionnera pas. Le répertoire serait signalé comme vide.
Diego Augusto Molina

@DiegoAugustoMolina si j'ai bien compris dans la question était que nous cherchons à vérifier si des fichiers existent (en tant que fichiers au littéral), c'est la raison pour laquelle l'argument -f a été utilisé. mais vos commentaires sont toujours valables.
igiannak

-2

Je n'aime pas le ls - A solutions affichées. Vous souhaiterez probablement tester si le répertoire est vide car vous ne souhaitez pas le supprimer. Ce qui suit fait cela. Si toutefois vous souhaitez simplement enregistrer un fichier vide, il est sûrement plus rapide de le supprimer et de le recréer que de lister éventuellement des fichiers infinis?

Cela devrait fonctionner ...

if !  rmdir ${target}
then
    echo "not empty"
else
    echo "empty"
    mkdir ${target}
fi

4
Cela ne fonctionne pas si l'utilisateur n'a pas l'autorisation d'écriture sur ${target}/...
Jens

Juste une mauvaise idée de faire un test destructeur. Entre autres, il introduit des conditions de course.
4dummies

-2

Fonctionne bien pour moi ceci (quand dir existe):

some_dir="/some/dir with whitespace & other characters/"
if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

Avec contrôle complet:

if [ -d "$some_dir" ]; then
  if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; else "Dir is NOT empty" fi
fi
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.