399 votes

Vérifier si un fichier existe avec un caractère générique dans un script shell

J'essaie de vérifier si un fichier existe, mais avec un joker. Voici mon exemple:

 if [ -f "xorg-x11-fonts*" ]; then
    printf "BLAH"
fi
 

Je l'ai aussi essayé sans les doubles guillemets.

616voto

Costi Ciudatu Points 13020

Le plus simple devrait être de s'appuyer sur ls de la valeur de retour (elle renvoie non nulle lorsque les fichiers n'existent pas):

if ls /path/to/your/files* &> /dev/null; then
    echo "files do exist"
else
    echo "files do not exist"
fi

J'ai redirigé l' ls de sortie pour le rendre complètement silencieux.


EDIT: étant donné que cette réponse a eu un peu d'attention (et très utile critique remarques en commentaires), ici, c'est une optimisation qui s'appuie également sur le glob de l'expansion, mais évite l'utilisation d' ls:

for f in /path/to/your/files*; do

    ## Check if the glob gets expanded to existing files.
    ## If not, f here will be exactly the pattern above
    ## and the exists test will evaluate to false.
    [ -e "$f" ] && echo "files do exist" || echo "files do not exist"

    ## This is all we needed to know, so we can break after the first iteration
    break
done

Ceci est très similaire à @grok12 réponse, mais il permet d'éviter l'inutile itération à travers l'ensemble de la liste.

81voto

flabdablet Points 1066

Si votre shell est un nullglob option et qu'il est allumé, un modèle générique qui correspond à aucune fichiers seront supprimés de la ligne de commande tout à fait. Cela rendra ls vois pas de chemin arguments, liste le contenu du répertoire courant et de réussir, ce qui est faux. GNU stat, qui échoue toujours si on leur donne pas d'arguments ou d'un argument de nommer un fichier inexistant, serait plus robuste. Aussi, l' &> opérateur de redirection est un bashism.

if stat --printf='' /path/to/your/files* 2>/dev/null
then
    echo found
else
    echo not found
fi

Mieux encore est de GNU trouver, qui peut gérer un générique de recherche à l'interne et de sortie dès que à ce qu'il trouve un fichier correspondant, plutôt que de perdre du temps de traitement est potentiellement énorme liste élargie par le shell; cela permet aussi d'éviter le risque que le shell peut débordement de sa ligne de commande de la mémoire tampon.

if test -n "$(find /dir/to/search -maxdepth 1 -name 'files*' -print -quit)"
then
    echo found
else
    echo not found
fi

Non-GNU versions de trouver peut ne pas avoir l' -maxdepth option est utilisée ici pour faire trouver de la recherche que l' /dir/de/de recherche au lieu de l'ensemble du répertoire arbre enraciné.

42voto

Pankaj Parashar Points 821

Voici ma réponse -

 files=(xorg-x11-fonts*)

if [ -e "${files[0]}" ];
then
    printf "BLAH"
fi
 

25voto

grok12 Points 754
 for i in xorg-x11-fonts*; do
if [ -f "$i" ]; then printf "BLAH" fi
done
 

Cela fonctionnera avec plusieurs fichiers et avec des espaces blancs dans les noms de fichiers.

20voto

Swift Points 6363

METTRE À JOUR:

Ok, maintenant j'ai définitivement la solution:

 files=$(ls xorg-x11-fonts* 2> /dev/null | wc -l)
if [ "$files" != "0" ]
then
   echo "Exists"
else
    echo "None found."
fi

> Exists
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X