GNU/Linux >> Tutoriels Linux >  >> Linux

Tester s'il existe des fichiers correspondant à un modèle afin d'exécuter un script ?

J'essaie d'écrire un if pour tester s'il existe des fichiers correspondant à un certain modèle. S'il y a un fichier texte dans un répertoire, il doit exécuter un script donné.

Mon code actuellement :

if [ -f /*.txt ]; then ./script fi

Veuillez donner quelques idées; Je veux seulement exécuter le script s'il y a un .txt dans le répertoire.

Réponse acceptée :

[ -f /*.txt ]

renverrait true uniquement s'il y en a un (et un seul) fichier non caché dans / dont le nom se termine par .txt et si ce fichier est un fichier normal ou un lien symbolique vers un fichier normal.

C'est parce que les caractères génériques sont développés par le shell avant d'être passés à la commande (ici [ ).

Donc s'il y a un /a.txt et /b.txt , [ sera passé 5 arguments :[ , -f , /a.txt , /b.txt et ] . [ se plaindrait alors que -f reçoit trop d'arguments.

Si vous voulez vérifier que le *.txt le motif se développe en au moins un fichier non caché (régulier ou non), dans le bash coque :

shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
  ./script "[email protected]" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"

shopt -s nullglob est bash spécifique (shopt est, nullglob vient en fait de zsh ), mais des shells comme ksh93 , zsh , yash , tcsh ont des déclarations équivalentes.

Avec zsh , le test pour existe-t-il des fichiers correspondant à un modèle peut être écrit en utilisant une fonction anonyme et le N (pour nullglob ) et Y1 (pour s'arrêter après la première recherche) qualificateur global :

if ()(($#)) *.txt(NY1); then
  do-something
fi

Notez que ceux-ci trouvent ces fichiers en lisant le contenu du répertoire, il n'essaie pas du tout d'accéder à ces fichiers, ce qui le rend plus efficace que les solutions qui appellent des commandes comme ls ou stat sur cette liste de fichiers calculée par le shell.

Le sh standard l'équivalent serait :

set -- [*].txt *.txt
case "$1$2" in
  ('[*].txt*.txt') ;;
  (*) shift; script "[email protected]"
esac

Le problème est qu'avec les shells Bourne ou POSIX, si un motif ne correspond pas, il s'étend à lui-même. Donc si *.txt se développe en *.txt , vous ne savez pas si c'est parce qu'il n'y a pas de .txt fichier dans le répertoire ou parce qu'il y a un fichier appelé *.txt . Utilisation de [*].txt *.txt permet de discriminer entre les deux.

Maintenant, si vous voulez vérifier que le *.txt correspond à au moins un regular fichier ou lien symbolique vers un fichier normal (comme votre [ -f *.txt ] vous suggère de faire), ou que tous les fichiers qui correspondent à *.txt sont réguliers fichiers (après la résolution du lien symbolique), c'est encore une autre affaire.

En relation :Comment générer un script de création de table sans clé primaire ni clé étrangère dans Oracle ?

Avec zsh :

if ()(($#)) *.txt(NY1-.); then
  echo "there is at least one regular .txt file"
fi
if ()(($#)) *.txt(NY1^-.); then
  echo "there is at least one non-regular .txt files"
fi

(supprimer le - si vous voulez faire le test avant la résolution des liens symboliques, c'est-à-dire considérer les liens symboliques comme des fichiers non réguliers, qu'ils pointent vers des fichiers normaux ou non).


Linux
  1. Est-il possible de savoir quel programme ou script a créé un fichier donné ?

  2. Fichiers Cat avec répertoire ?

  3. Remplacer les lignes correspondant à un motif par des lignes d'un autre fichier dans l'ordre ?

  4. Comment rechercher dans des fichiers spécifiques correspondant à un modèle ?

  5. Vérifier qu'il y a au moins deux arguments donnés dans un script bash

Exécuter des fichiers binaires sous Linux

Rechercher et supprimer le fichier le plus ancien s'il y a plus de X fichiers dans un répertoire sous Linux

Copiez tous les fichiers correspondant au modèle du répertoire et des sous-répertoires dans un seul répertoire

Trouver un fichier correspondant à un certain modèle et donner ce nom de fichier comme valeur à une variable dans un script shell ?

Comment savoir s'il y a des fichiers dans un dossier et quitter en conséquence (en KSH)

Comment utiliser la commande find pour supprimer les fichiers correspondant à un modèle ?