web-dev-qa-db-fra.com

Une doublure pour vérifier le fichier existe

Objectif: Vérifier la présence d'un fichier de sauvegarde .tgz contenant la date du jour; sortie 1 pour OK, 0 pour aucun fichier.

Je suis un surgeon pour un liners :) Par exemple en PHP (et à peu près similaire en Javascript), dans divers scénarios, j'aime faire quelque chose comme

<?php
echo (date("d")==1)?"Monday":"Not Monday";
?>

Existe-t-il une syntaxe similaire dans Bash? Je sais comment vérifier la présence d'un fichier normal en utilisant -f FILENAME, je veux seulement que la commande imprime 1 ou 0 :)

9
DavDav

Vous pouvez simplement faire ceci:

#to check if it's a regular file
[ -f "/you/file.file" ] && echo 1 || echo 0
#to check if a file exist
[ -e "/you/file.file" ] && echo 1 || echo 0

En Shell ce personnage [ signifie test, -e si le fichier existe ] fin du test && si la commande retourne true, exécutez la commande après, || si la commande retourne false exécuter la commande après.
Cela devrait fonctionner dans Shell et bash

22
Kiwy
if [ ! -f /tmp/foo.txt ]; then echo "File not found!"; else echo "file found"; fi
16
user88036

Avec zsh:

(){echo $#} *"$(date +%Y-%m-%d)"*.tgz(DN)

Afficherait le nombre de fichiers dans le répertoire actuel dont le nom contient la date actuelle au format AAAA-mm-jj et se terminerait par .tgz Sous forme de nombre décimal. Remplacez (DN) Par (DN[1]) Si vous ne voulez que 0 ou 1.

Pour l'utiliser comme condition dans une instruction if, vous pouvez faire:

if ()(($#)) *"$(date +%Y-%m-%d)"*.tgz(DN); then
   echo found
else
   echo none found
fi

Dans bash

l'équivalent pourrait être:

(shopt -s nullglob dotglob; set -- *"$(date +%Y-%m-%d)"*.tgz; echo "$#")

(remplacez "$#" par "$(($#>0))" pour obtenir 0 ou 1).

et

if (shopt -s nullglob dotglob; set -- *"$(date +%Y-%m-%d)"*.tgz; (($#))); then
   echo found
else
   echo none found
fi

Avec ksh93:

(FIGNORE='@(.|..)'; set -- ~(N)*"$(date +%Y-%m-%d)"*.tgz; echo "$#")

et

if (FIGNORE='@(.|..)'; set -- ~(N)*"$(date +%Y-%m-%d)"*.tgz; (("$#"))); then...

POSIXly

ls -qA | grep -c "$(date +%Y-%m-%d).*\.tgz$"

pour le comte.

ls -qA | grep -q "$(date +%Y-%m-%d).*\.tgz$"; echo "$(($? == 0))"

pour 0 ou 1 et:

Et:

if ls -qA | grep -q "$(date +%Y-%m-%d).*\.tgz$"; then...

Bien que la sagesse courante ne consiste pas à analyser la sortie de ls, ici avec -q, Nous nous assurons qu'il y a un fichier par ligne et le remplacement des caractères non imprimables par ? ne devrait pas affecter le greping de notre modèle, il devrait donc être relativement sûr.

Vous pouvez voir des différences si les noms de fichiers contiennent des séquences d'octets qui ne forment pas de caractères valides. Un avantage est que vous obtiendrez un message d'erreur si le répertoire courant n'est pas lisible.

9

Vous pouvez utiliser cette commande:

test -e *$(date).tgz && echo 1 || echo 0
5
mrc02_kr

Comme encore une autre variante, si vous connaissiez le format exact du nom de fichier que vous cherchiez, vous pourriez utiliser

[ ! -f FILENAME ]; echo $?

ou

echo `[ ! -f FILENAME ]` $?

cependant, cela ne pouvait pas faire face aux caractères génériques, donc les fichiers se terminant par .tgz contenant la date d'aujourd'hui auraient besoin de quelque chose de plus complexe, comme

echo $( for entry in *$(date --rfc-3339=date)*.tgz; do [ -f "$entry" ] && exit 1; done; exit 0 ) $?
4
Grump

Je sais que vous avez demandé Bash, mais si vous recherchez un programme en ligne de commande qui fonctionnera, je recommande Python:

python -c "import os; exists = os.path.isfile('myFile.txt'); print(int(exists))"
0
user1717828
ls filename 2> /dev/null && echo 1 || echo 0

Ou, si vous le souhaitez dans une variable

EXISTS=$(ls filename 2> /dev/null && echo 1 || echo 0)
0
pkuhar