web-dev-qa-db-fra.com

Rechercher des fichiers dans plusieurs noms de dossier

J'essaie de lister tous les fichiers de dir1, dir2, dir3 et dir4 qui peut se trouver n'importe où dans un sous-répertoire de mon cwd à l'aide de la commande find. J'ai essayé ce qui suit sans succès:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

J'ai essayé posix-extended ainsi que. Comment lister ces fichiers?

48
Aaron

Et si vous souhaitez rechercher trois dossiers nommés foo, bar et baz pour tous les fichiers *.py, Utilisez cette commande:

find foo bar baz -name "*.py"

donc si vous voulez afficher des fichiers de dir1dir2dir3 utilisez find dir1 dir2 dir3 -type f

essayez cette find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;

65
harish.venkat

Il est préférable d'utiliser la directive -path:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

Ce qui signifie: trouver tous les fichiers dans le répertoire courant où il y a 'dir1' ou 'dir2' ou 'dir3' ou 'dir4' dans le chemin.

10

Juste pour que tout le monde le sache. Ajouter .*/ avant chaque dir a résolu le problème car le regex correspond au chemin complet qu'il semble.

4
Aaron

Ceci est ma première idée après avoir lu les réponses précédentes:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

Cela tient compte du fait que l'expression régulière doit correspondre à l'ensemble du nom de fichier et est plus facile à comprendre.

3
Ronin Tom

Exemple de recherche rapide (!) De fichiers particuliers (access_log) dans plusieurs emplacements définis par le caractère générique (répertoire personnel) et le répertoire général des journaux Apache2 appliquant également le filtrage des noms pour exclure les journaux SSL et les anciens journaux compressés. Ne répond pas directement à la question ici mais peut être utile pour quelqu'un qui a trouvé ces instructions (comme moi).

find / \( -path "*var/log/Apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

Soyez prudent avec les espaces, spécialement près de \( et \).

Soit dit en passant, je l'ai utilisé pour apachetop, pour trouver les sites Web les plus actifs sur mon serveur.

apachetop -d1 -s9 -p $(find / \( -path "*var/log/Apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)
2
Kristjan Adojaan

vous n'avez pas besoin de spécifier dir1 à dir4 par nom si vous utilisez regextype

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: rechercher des fichiers et non des répertoires
  • regextype sed: utilise sed regextype
  • regex: recherches utilisant des expressions rationnelles dans tout le chemin
  • ".*/dir[1-4]/[a-z0-9]*":. * au début signifie n'importe quel nombre de caractères qui pourraient être de type (char/number/backslash (/) etc); dir [1-4] signifie rechercher "dir" suivi d'un nombre entre 1 et 4;/[^ /] * indique que la suite de dir1-4 omet tous les chemins d'accès qui contiennent /, donc elle ne renvoie que les fichiers du répertoire dir1-dir4 et ignore tous les sous-répertoires qui peuvent se trouver dans dir1-dir4.

créé un répertoire pour que vous puissiez le tester: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017

2
alpha_989

Je sais que vous avez spécifié qu'en utilisant find, mais uniquement pour afficher d'autres options pouvant être utilisées, vous pouvez utiliser xargs:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

Vous pouvez avoir un fichier nommé "dossiers" qui contient quelque chose comme:

$ cat folders
dir1
dir2
dir3
dir4

Ensuite, vous pouvez faire quelque chose comme ceci:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

xargs à mon avis, je me sens plus polyvalent que find -exec. Vous pouvez aussi faire des trucs fous comme

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
0
Cuauhtli