Je veux tester si un répertoire ne contient aucun fichier. Si tel est le cas, je vais ignorer certains traitements.
J'ai essayé ce qui suit:
if [ ./* == "./*" ]; then
echo "No new file"
exit 1
fi
Cela donne l'erreur suivante:
line 1: [: too many arguments
Y a-t-il une solution/alternative?
if [ -z "$(ls -A /path/to/dir)" ]; then
echo "Empty"
else
echo "Not Empty"
fi
En outre, il serait intéressant de vérifier si le répertoire existe avant.
if [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; then
echo "Empty directory"
else
echo "Not empty or NOT a directory"
fi
Pas besoin de compter quoi que ce soit ou de globes Shell. Vous pouvez également utiliser read
en combinaison avec find
. Si la sortie de find
est vide, vous retournerez false
:
if find /some/dir -mindepth 1 | read; then
echo "dir not empty"
else
echo "dir empty"
fi
Cela devrait être portable.
#!/bin/bash
if [ -d /path/to/dir ]; then
# the directory exists
[ "$(ls -A /path/to/dir)" ] && echo "Not Empty" || echo "Empty"
else
# You could check here if /path/to/dir is a file with [ -f /path/to/dir]
fi
Cela fera le travail dans le répertoire de travail courant (.):
[ `ls -1A . | wc -l` -eq 0 ] && echo "Current dir is empty." || echo "Current dir has files (or hidden files) in it."
ou la même commande divisée sur trois lignes juste pour être plus lisible:
[ `ls -1A . | wc -l` -eq 0 ] && \
echo "Current dir is empty." || \
echo "Current dir has files (or hidden files) in it."
Il suffit de remplacer ls -1A . | wc -l
par ls -1A <target-directory> | wc -l
si vous devez l'exécuter sur un autre dossier cible.
Edit : J'ai remplacé -1a
par -1A
(voir le commentaire @Daniel)
Utilisez le suivant:
count="$( find /path -mindepth 1 -maxdepth 1 | wc -l )"
if [ $count -eq 0 ] ; then
echo "No new file"
exit 1
fi
De cette façon, vous êtes indépendant du format de sortie de ls
. -mindepth
ignore le répertoire lui-même, -maxdepth
empêche la défense récursive dans des sous-répertoires pour accélérer les choses.
Un hacky, mais uniquement bash, sans PID:
is_empty() {
test -e "$1/"* 2>/dev/null
case $? in
1) return 0 ;;
*) return 1 ;;
esac
}
Ceci tire parti du fait que test
construit se termine avec 2 si plus d'un argument est donné après -e
: D'abord, "$1"/*
glob est développé par bash. Cela se traduit par un argument par fichier. Alors
S'il n'y a aucun fichier, l'astérisque dans test -e "$1"*
ne se développe pas, donc Shell retourne à l'essai du fichier nommé *
, qui renvoie 1.
... sauf s'il y a réellement un fichier nommé exactement *
, l'astérisque se développe alors, astérisque, qui aboutit au même appel que ci-dessus, c'est-à-dire. test -e "dir/*"
, cette fois, retourne 0. (Merci @TrueY pour l'avoir signalé.)
S'il y a un fichier, test -e "dir/file"
est exécuté, ce qui renvoie 0.
Mais s'il y a plus de fichiers que 1, test -e "dir/file1" "dir/file2"
est exécuté, ce qui est signalé par bash comme une erreur d'utilisation, c'est-à-dire 2.
case
encapsule toute la logique pour que seul le premier cas, avec 1 état de sortie, soit signalé comme ayant abouti.
Problèmes possibles que je n'ai pas vérifiés:
Il y a plus de fichiers que le nombre d'arguments autorisés - je suppose que cela pourrait se comporter de la même manière que le cas de 2 fichiers ou plus.
Ou alors il y a un fichier avec un nom vide - je ne suis pas sûr que ce soit possible avec n'importe quel système d'exploitation/système d'exploitation.
Utiliser un tableau:
files=( * .* )
if (( ${#files[@]} == 2 )); then
# contents of files array is (. ..)
echo dir is empty
fi
Avec FIND (1) (sous Linux et FreeBSD), vous pouvez regarder de manière non récursive une entrée de répertoire via "-maxdepth 0" et tester si elle est vide avec "-empty". Appliqué à la question cela donne:
if test -n "$(find ./ -maxdepth 0 -empty)" ; then
echo "No new file"
exit 1
fi
if find "${DIR}" -Prune ! -empty -exit 1; then
echo Empty
else
echo Not Empty
fi
EDIT: Je pense que cette solution fonctionne bien avec gnu find, après un quick regardez le implementation . Mais cela peut ne pas fonctionner avec, par exemple, recherche de netbsd . En effet, celui-ci utilise le champ st_size de stat (2). Le manuel le décrit comme:
st_size The size of the file in bytes. The meaning of the size
reported for a directory is file system dependent.
Some file systems (e.g. FFS) return the total size used
for the directory metadata, possibly including free
slots; others (notably ZFS) return the number of
entries in the directory. Some may also return other
things or always report zero.
Une meilleure solution, également plus simple, est:
if find "${DIR}" -mindepth 1 -exit 1; then
echo Empty
else
echo Not Empty
fi
De plus, la solution -Prune dans la 1ère est inutile.
EDIT: no -exit for gnu find .. la solution ci-dessus est bonne pour la recherche de NetBSD. Pour GNU find, cela devrait fonctionner:
if [ -z "`find \"${DIR}\" -mindepth 1 -exec echo notempty \; -quit`" ]; then
echo Empty
else
echo Not Empty
fi
Je pense que la meilleure solution est:
files=$(shopt -s nullglob; shopt -s dotglob; echo /MYPATH/*)
[[ "$files" ]] || echo "dir empty"
grâce à https://stackoverflow.com/a/91558/520567
Ceci est une édition anonyme de ma réponse qui pourrait être utile ou non à quelqu'un: Une légère modification indique le nombre de fichiers
files=$(shopt -s nullglob dotglob; s=(MYPATH/*); echo ${s[*]})
echo "MYPATH contains $files files"
Cela fonctionnera correctement même si les noms de fichiers contiennent des espaces.
Qu'en est-il de tester si le répertoire existe et non vide dans une instruction if
if [[ -d path/to/dir && -n "$(ls -A path/to/dir)" ]]; then
echo "directory exists"
else
echo "directory doesn't exist"
fi
Tout cela est génial - il suffit d’en faire un script pour que je puisse rechercher des répertoires vides sous le répertoire actuel. Le fichier ci-dessous devrait être placé dans un fichier appelé 'findempty', placé quelque part dans le chemin afin que bash puisse le trouver, puis exécuter chmod 755. Peut facilement être adapté à vos besoins spécifiques, je suppose.
#!/bin/bash
if [ "$#" == "0" ]; then
find . -maxdepth 1 -type d -exec findempty "{}" \;
exit
fi
COUNT=`ls -1A "$*" | wc -l`
if [ "$COUNT" == "0" ]; then
echo "$* : $COUNT"
fi
Ce travail pour moi, pour vérifier et traiter les fichiers dans le répertoire ../IN
, en considérant que le script est dans le répertoire ../Script
:
FileTotalCount=0
for file in ../IN/*; do
FileTotalCount=`expr $FileTotalCount + 1`
done
if test "$file" = "../IN/*"
then
echo "EXITING: NO files available for processing in ../IN directory. "
exit
else
echo "Starting Process: Found ""$FileTotalCount"" files in ../IN directory for processing."
# Rest of the Code