web-dev-qa-db-fra.com

Trouver le fichier en faisant correspondre sur son chemin

J'ai un répertoire contenant un certain nombre de sous-répertoires. Chacun de ces sous-répertoires contient un sous-répertoire portant le même nom. Je voudrais produire une liste de tous ces fichiers sur la ligne de commande. Donc, par exemple, si j'ai:

dir1/
    file1.txt
    subdir/
        relevant_file1.c
        relevant_file2.c
dir2/
    file2.txt
    subdir/
        relevant_file3.txt
        relevant_file4.Java
dir3/
    subdir/
        relevant_file5.cpp
    irrelevant_subdir/
        unimportant_file.txt
dir4/
    subdir/

J'aimerais avoir la sortie suivante:

dir1/subdir/relevant_file1.c
dir1/subdir/relevant_file2.c
dir2/subdir/relevant_file3.txt
dir2/subdir/relevant_file4.Java
dir3/subdir/relevant_file5.cpp

Je présume que cela ne devrait pas être aussi difficile avec find, mais je n’ai pas tout à fait été capable de le comprendre. Il est difficile de rechercher ce problème car il est si spécifique, et la simple recherche de "trouver un fichier par correspondance sur son chemin" ne produit rien d’utile.

7
Mees de Vries

essaye ça

find */subdir -type f
8
Carl

Vous n'avez pas réellement besoin de find pour cela. Un simple ls fera:

$ ls -1 */subdir/*
dir1/subdir/relevant_file1.c
dir1/subdir/relevant_file2.c
dir2/subdir/relevant_file3.txt
dir2/subdir/relevant_file4.Java
dir3/subdir/relevant_file5.cpp

Ou, si vous voulez faire quelque chose avec ces fichiers et pas simplement les lister, utilisez les globs de shell:

for file in */subdir/*; do command "$file"; done

Bien sûr, cela listera tout ce qui se trouve dans n'importe quel sous-répertoire appelé subdir. Y compris les répertoires, liens symboliques, fichiers de périphérique ou toute autre chose. Si vous voulez le limiter aux fichiers normaux, utilisez find "*/subdir" -type fcomme suggéré par @Carl ou ajoutez un test de fichier:

for file in */subdir/*; do [ -f "$file" ] && command "$file"; done
8
terdon

Une meilleure solution de contournement avec find consiste à utiliser l'option -path.

find -path "*/subdir/*" -type f

C'est plus utile lorsque nous avons une structure plus complexe. quelque chose comme:

.
├── dir1
│   ├── gooddir
│   │   └── subdir
│   │       └── file.txt
│   ├── irrelevant_subdir
│   │   └── file.txt
│   └── subdir
│       └── file.txt
└── dir2
    ├── gooddir
    │   └── subdir
    │       └── file.txt
    ├── irrelevant_subdir
    │   └── file.txt
    └── subdir
        └── file.txt

Dans l'exemple ci-dessus, quelque chose comme find */subdir -type f ne trouve que les fichiers dans un premier subdir. Cependant find -path "*/subdir/*" -type f fonctionnera bien.

2
Ravexina

Il suffit d'utiliser l'outil approprié:

locate "/subdir/"

Vous voudrez peut-être (ré) exécuter:

Sudo updatedb

si vous avez besoin d'actualiser la base de données de Locate (par exemple, si vous souhaitez rechercher les fichiers récemment ajoutés), mais il doit être créé via des crontabs tous les jours (si le PC est en cours d'exécution à ce moment).

Si vous avez besoin de la mise à jour initialeb, elle peut sembler plus lente que la recherche spécifique, mais au final, elle est plus rapide car toutes les requêtes suivantes sont effectuées FAST.

1
Olivier Dulac