J'essaie de trouver tous les fichiers avec une extension spécifique dans un répertoire et ses sous-répertoires avec mon bash (dernière version Ubuntu LTS).
C'est 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, quand je lance ce script en terminal, il dit:
[: 29: in: unexpected operator
(avec $extension
au lieu de 'in'
)
Qu'est-ce qui se passe ici, où est l'erreur? Mais cette accolade
find $directory -type f -name "*.in"
est un peu plus court que ce tout (et plus sûr - traite des espaces dans les noms de fichiers et noms de répertoires).
Votre script échoue probablement pour les entrées dont le nom ne contient pas .
, ce qui rend $extension
vide.
find {directory} -type f -name '*.extension'
exemplepour trouver tous les fichiers csv du répertoire courant et de ses sous-répertoires
find . -type f -name '*.csv'
La syntaxe que j'utilise est un peu différente de celle suggérée par @Matt:
find $directory -type f -name \*.in
(c'est une frappe de moins).
Sans utiliser find
name__:
du -a $directory | awk '{print $2}' | grep '\.in$'
{
après browsefolders ()
$in
devraient être $suffix
cut
ne vous donne que la partie centrale de front.middle.extension
. Vous devriez lire votre manuel Shell sur ${varname%%pattern}
et ses amis.Je suppose que vous faites cela comme un exercice de script Shell, sinon la solution find
déjà proposée est la voie à suivre.
Pour vérifier la syntaxe du shell, sans exécuter de script, utilisez sh -n scriptname
.
Pour rechercher tous les fichiers pom.xml
dans votre répertoire actuel et les imprimer, vous pouvez utiliser:
find . -name 'pom.xml' -print
Bien que l’utilisation de la commande find
puisse être utile ici, le shell lui-même fournit des options permettant de satisfaire à cette exigence sans outils tiers. Le shell bash
fournit une option de prise en charge étendue globale à l'aide de laquelle vous pouvez obtenir les noms de fichiers sous des chemins récursifs correspondant aux extensions souhaitées.
L'option étendue est extglob
et doit être définie à l'aide de l'option shopt
comme ci-dessous. Les options sont activées avec le support -s
et désactivées avec le drapeau -u
. En outre, vous pouvez utiliser plusieurs options supplémentaires, à savoir nullglob
, dans lesquelles un glob inégalé est entièrement balayé, remplacé par un ensemble de zéro mot. Et globstar
qui permet de recurse à travers tous les répertoires
shopt -s extglob nullglob globstar
Il ne vous reste plus qu'à former l'expression globale pour inclure les fichiers d'une certaine extension, ce que vous pouvez faire comme ci-dessous. Nous utilisons un tableau pour renseigner les résultats globaux car, une fois cités correctement et développés, les noms de fichiers avec des caractères spéciaux resteraient intacts et ne seraient pas cassés à cause du fractionnement de Word par le shell.
Par exemple, pour répertorier tous les fichiers *.csv
dans les chemins récursifs
fileList=(**/*.csv)
L'option **
permet de recurse à travers les sous-dossiers et *.csv
correspond à une expansion globale pour inclure tout fichier des extensions mentionnées. Maintenant, pour imprimer les fichiers réels, faites juste
printf '%s\n' "${fileList[@]}"
Utiliser un tableau et effectuer une extension citée appropriée est la méthode la plus appropriée dans les scripts Shell, mais pour une utilisation interactive, vous pouvez simplement utiliser ls
avec l'expression glob en tant que
ls -1 -- **/*.csv
Cela pourrait très bien être étendu pour correspondre à plusieurs fichiers, c'est-à-dire un fichier se terminant par plusieurs extensions (similaire à l'ajout de plusieurs indicateurs dans la commande find
). Par exemple, considérons le cas où il faut obtenir tous les fichiers d’image récursifs, c’est-à-dire avec les extensions *.gif
, *.png
et *.jpg
, c’est tout ce dont vous avez besoin.
ls -1 -- **/+(*.jpg|*.gif|*.png)
Cela pourrait très bien être étendu pour avoir des résultats nuls aussi. Avec la même syntaxe, on pourrait utiliser les résultats du glob pour exclure des fichiers d'un certain type. Supposons que vous souhaitiez exclure les noms de fichiers avec les extensions ci-dessus, vous pouvez le faire.
excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"
La construction !()
est une opération de négation visant à ne pas inclure les extensions de fichier répertoriées à l'intérieur et |
est un opérateur d'alternance utilisé dans la bibliothèque des expressions régulières étendues pour effectuer une correspondance OR des globs.
Notez que cette prise en charge étendue de glob n'est pas disponible dans POSIX Bourne Shell et qu'elle est purement spécifique aux versions récentes de bash
. Donc, si vous envisagez la portabilité des scripts exécutés sur des shells POSIX et bash
, cette option ne conviendrait pas.
find $directory -type f -name "*.in"|grep $substring
for file in "${LOCATION_VAR}"/*.Zip
do
echo "$file"
done
find "$PWD" -type f -name "*.in"