J'essaie de trouver tous les fichiers avec une extension spécifique dans un répertoire et ses sous-répertoires avec ma bash (dernière version Ubuntu LTS).
Voici ce qui est écrit dans un fichier script:
#!/bin/bash
directory="/home/flip/Desktop"
suffix="in"
browsefolders ()
for i in "$1"/*;
do
echo "dir :$directory"
echo "filename: $i"
# echo ${i#*.}
extension=`echo "$i" | cut -d'.' -f2`
echo "Erweiterung $extension"
if [ -f "$i" ]; then
if [ $extension == $suffix ]; then
echo "$i ends with $in"
else
echo "$i does NOT end with $in"
fi
elif [ -d "$i" ]; then
browsefolders "$i"
fi
done
}
browsefolders "$directory"
Malheureusement, lorsque je démarre ce script dans le terminal, il dit:
[: 29: in: unexpected operator
(avec $extension
au lieu de 'in'
)
Que se passe-t-il ici, où est l'erreur? Mais cette accolade frisée
Réponses:
est un peu plus court que tout cela (et plus sûr - traite des espaces dans les noms de fichiers et les noms de répertoire).
Votre script échoue probablement pour les entrées qui n'ont pas
.
de nom, ce qui$extension
les rend vides.la source
find
est récursif par défaut. vous pouvez limiter les profondeurs si vous le souhaitez (voir la page de manuel).Exemple: pour rechercher tous les
csv
fichiers du répertoire courant et de ses sous-répertoires, utilisez:la source
La syntaxe que j'utilise est un peu différente de celle suggérée par @Matt:
(c'est une frappe de moins).
la source
Sans utiliser
find
:la source
grep
n'est pas vraiment nécessaire ici.awk
a des expressions régulières et pourrait limiter sa sortie à des valeurs correspondant à un modèle.awk|grep
est un anti-motif. Laissez awk faire le salut.{
manque un aprèsbrowsefolders ()
$in
devrait être$suffix
cut
vous n'obtient que la partie médiane defront.middle.extension
. Vous devriez lire votre manuel shell${varname%%pattern}
et vos amis.Je suppose que vous faites cela comme un exercice de script shell, sinon la
find
solution déjà proposée est la voie à suivre.Pour vérifier la syntaxe correcte du shell, sans exécuter de script, utilisez
sh -n scriptname
.la source
la source
Bien que l'utilisation de la
find
commande puisse être utile ici, le shell lui-même fournit des options pour répondre à cette exigence sans aucun outil tiers. Lebash
shell fournit une option de prise en charge globale étendue à l'aide de laquelle vous pouvez obtenir les noms de fichiers sous des chemins récursifs qui correspondent aux extensions souhaitées.L'option étendue est celle
extglob
qui doit être définie à l'aide de l'shopt
option ci-dessous. Les options sont activées avec le-s
support et désactivées avec le-u
drapeau. De plus, vous pouvez utiliser plusieurs options, c'est-nullglob
à- dire dans lesquelles un glob inégalé est entièrement balayé, remplacé par un ensemble de zéro mot. Etglobstar
cela permet de récuser à travers tous les répertoiresMaintenant, tout ce que vous devez faire est de former l'expression glob pour inclure les fichiers d'une certaine extension que vous pouvez faire comme ci-dessous. Nous utilisons un tableau pour remplir les résultats globaux car lorsqu'ils sont correctement cités et développés, les noms de fichiers avec des caractères spéciaux restent intacts et ne sont pas cassés en raison de la séparation des mots par le shell.
Par exemple pour lister tous les
*.csv
fichiers dans les chemins récursifsL'option
**
est de récuser à travers les sous-dossiers et*.csv
est une extension globale pour inclure n'importe quel fichier des extensions mentionnées. Maintenant, pour imprimer les fichiers réels, faites simplementUtiliser un tableau et faire une expansion entre guillemets appropriée est la bonne façon lorsqu'il est utilisé dans des scripts shell, mais pour une utilisation interactive, vous pouvez simplement utiliser
ls
avec l'expression glob commeCela pourrait très bien être étendu pour correspondre à plusieurs fichiers, c'est-à-dire un fichier se terminant par plusieurs extensions (c'est-à-dire similaire à l'ajout de plusieurs indicateurs dans la
find
commande). Par exemple, considérez le cas où vous devez obtenir tous les fichiers image récursifs, c'est-à-dire les extensions*.gif
,*.png
et*.jpg
tout ce dont vous avez besoin estCela pourrait très bien être étendu pour avoir également des résultats négatifs. Avec la même syntaxe, on pourrait utiliser les résultats du glob pour exclure des fichiers d'un certain type. Supposons que vous souhaitez exclure les noms de fichiers avec les extensions ci-dessus, vous pouvez le faire
La construction
!()
est une opération de négation qui n'inclut aucune des extensions de fichier répertoriées à l'intérieur et|
est un opérateur d'alternance tout comme utilisé dans la bibliothèque des expressions régulières étendues pour effectuer une correspondance OU des globes.Notez que cette prise en charge étendue de glob n'est pas disponible dans le shell POSIX bourne et son purement spécifique aux versions récentes de
bash
. Donc, si vous envisagez la portabilité des scripts exécutés sur POSIX et lesbash
shells, cette option ne serait pas la bonne.la source
Pour rechercher tous les
pom.xml
fichiers dans votre répertoire actuel et les imprimer, vous pouvez utiliser:la source
la source
la source