Comment sortir d’un script shell s’il n’existe pas de fichier ciblé

Compte tenu du script ci-dessous, je voudrais éviter l’exécution du pipeline si un fichier n’existe pas.

Comment puis-je quitter le script immédiatement si le fichier txt n’est pas trouvé?

ls */*.txt | grep ab1 | awk '{print $1, $1}' | sed "s/\"/\"\"/g" | xargs -L1 mv 

Vous pouvez vérifier l’existence d’un fichier avec quelque chose comme:

 if [[ -f x.txt ]] ; then echo file exists. fi 

Pour en sortir si ce n’est pas le cas, quelque chose comme cela suffirait:

 if [[ ! -f x.txt ]] ; then echo 'File "x.txt" is not there, aborting.' exit fi 

Le -f est l’ une des nombreuses expressions conditionnelles que vous pouvez utiliser. Si vous regardez la page de manuel bash sous CONDITIONAL EXPRESSIONS , vous en verrez une multitude.


Si (comme indiqué dans une mise à jour de la question) vous souhaitez vérifier si un joker génère des fichiers, vous pouvez simplement le développer, en éliminant les erreurs. S’il n’y en a pas, vous allez vous retrouver avec une chaîne vide qui peut être détectée avec -z :

 if [[ -z "$(ls -1 */*.txt 2>/dev/null | grep ab1)" ]] ; then echo 'There are no "*/*.txt" files.' exit fi 

Notez que j’ai utilisé -1 pour forcer un fichier par ligne même si Linux le fait par défaut si le périphérique de sortie n’est pas un terminal (à partir de la mémoire). C’est juste au cas où vous essayez ceci sur une machine qui n’en force pas une par ligne dans ce cas.


Gardez cependant à l’esprit que si vous avez des espaces dans vos noms de fichiers, utiliser ls et awk pour extraire la colonne 1 ne fonctionnera pas trop bien. Par exemple, le fichier abc ab1.txt entraînera l’extraction du seul bit abc .

Utiliser find avec -print0 , combiné avec xargs avec -0 est la manière habituelle de traiter correctement les fichiers qui peuvent contenir des caractères “spéciaux”. Il existe de nombreuses autres options que vous pouvez find pour vous assurer que seuls les fichiers requirejs sont traités, tels que -maxdepth pour limiter la distance -maxdepth dans l’arborescence et -name pour filtrer correctement les noms de fichiers.

Cependant, si vous savez que vous ne disposerez jamais de ces types de fichiers, il est probablement acceptable d’utiliser la solution ls , assurez-vous simplement que vous êtes à l’aise avec ses lacunes.

Utiliser le test

Un moyen rapide et rapide de tester l’existence:

 test -e $FILENAME || exit 

Vous pouvez la chaîner en faisant:

 test -e $FILENAME && something | something-else 

Dans ce cas, something et something-else ne sera exécuté que si le fichier existe.

Par exemple:

 ➤ test -e ~/.bashrc && echo True || echo False True ➤ test -e ./exists-not && echo True || echo False False 

Mis à part: Notez que [ est un alias pour le test . La sémantique de [[ est définie par bash et se trouve sur la page de manuel bash

Toutefois…

… vous feriez probablement mieux d’utiliser find pour récupérer vos fichiers:

 find ./ -maxdepth 2 -name "*ab1*.txt" -exec do-something-to-filename '{}' \; 

Comme la sortie de ls ne peut pas être analysée de manière fiable. Cela n’exécutera également que la commande do-something-to-filename si le nom du fichier existe, ce que je pense que vous essayez de faire.

{} sera remplacé par le nom de fichier pour chaque appel de do-something-to-filename .

find ... -exec ... ou find ... -print0 | xargs -0 ... find ... -print0 | xargs -0 ... est généralement correct, mais vous pouvez le faire directement avec un glob en utilisant l’option nullglob de bash:

 bash-3.2$ echo *foo *foo bash-3.2$ shopt -s nullglob bash-3.2$ echo *foo bash-3.2$ 

Selon le rest de votre script, vous pouvez vouloir ou ne pas réinitialiser cela avec shopt -u nullglob .

J’ai essayé cela et cela a fonctionné pour moi

 test -s <> && exit 0 || <> 

Notez que je quitte réellement lorsque le fichier n’est pas présent