Comment renvoyer uniquement les noms de fichiers à partir de la commande find?

13

Je cherche à obtenir une liste de noms de fichiers uniquement (sans le reste du chemin) lors de l'exécution de la commande find à partir d'un terminal. Comment puis-je accomplir cela sur le mac?

blueberryfields
la source

Réponses:

17

Avec le nom de base:

find . -type f -exec basename {} \;

Paulo Almeida
la source
À quoi servent les accolades?
nullpotent
nom_base est exécuté une fois pour chaque fichier trouvé, indiqué par {}.
Ярослав Рахматуллин
quelle est la moyenne des \ et; ?
neouyghur
@neouyghur ;met fin à l' -execaction. Le \ est nécessaire car a ;également une signification particulière pour le shell.
8bittree
6

Evilsoup a mentionné que ce qui a été publié ne fonctionne pas pour les noms de fichiers espacés. Vous pouvez donc utiliser à la place:

find . -type f -print0 | while IFS= read -r -d '' filename; do echo ${filename##*/}; done
nerdwaller
la source
Cela cassera les fichiers avec des espaces dans leurs noms (voir l' analyse syntaxique de ls sur le wiki de greg)
evilsoup
+1 pour la vitesse. Je ne sais pas si j'ai fait quelque chose de mal, mais celui-ci a pris 1 seconde sur mon $ HOME, tandis que tous les autres ont pris environ 10 secondes. Bien sûr, il me faudrait plus de 10 secondes pour le rechercher et le saisir.
Paulo Almeida
2

Avec GNU find, vous pouvez faire:

 find ~/tmp/ -printf "%f\n"

Cela vaut probablement aussi la peine d'essayer sous OS X.

Ярослав Рахматуллин
la source
2
-printfest pas pris en charge sur BSD OS X find.
Daniel Beck
1
En outre, -printfn'a que peu de rapport avec le C printfou l'utilitaire shell POSIX printf. L'utilisation de ce nom de fonction historique pour quelque chose de différent est très mal envisagée. Les gars BSD conservateurs le voient probablement de la même manière, donc nous ne verrons probablement pas de clone -printfdans la découverte BSD, sous ce nom.
Kaz
Je ne suis pas d'accord pour dire qu'il est mal envisagé d'utiliser un nom de fonction familier pour effectuer une tâche similaire dans un contexte différent. Pourquoi BSD ne le supportera probablement jamais, c'est une autre affaire.
Ярослав Рахматуллин
2

Il existe un meilleur moyen de supprimer tout sauf la dernière partie d'un chemin de fichier; avec awk. C'est mieux car awk n'est pas exécuté une fois pour chaque fichier. Dans certains cas, cela compte.

find ~/tmp/ -type f  | awk -F/ '{ print $NF }'

Nous recherchons uniquement les fichiers dans ~ / tmp et nous obtenons une liste où chaque entrée est séparée par des barres obliques. Par conséquent, nous utilisons une barre oblique comme séparateur de champ (-F /) et imprimons le paramètre de champ ($ 1 .. $ 9) qui correspond au dernier champ ($ NF).

Ярослав Рахматуллин
la source
C'est le plus rapide que j'ai testé.
Paulo Almeida
J'ai utilisé Cygwin ces derniers temps, et créer un processus dans Windows coûte très cher ...
Ярослав Рахматуллин
2

MODIFIER :

En utilisant sed:

$ find . -type f | sed 's/.*\///'

Utilisation de la commande xargs , comme mentionné dans la réponse de @nerdwaller

$ find . -type f -print0 | xargs --null -n1 basename
stderr
la source
1
Merci d'avoir signalé celui-là, +1, je n'ai pas beaucoup utilisé xargs ... Certainement, car vous avez supprimé pas mal de caractères de ma commande.
nerdwaller
Celui-ci se casse lorsque les fichiers ont des espaces. Cela fonctionne comme ceci, au moins dans un test rapide:find . -type f -print0| xargs --null -n1 basename
Paulo Almeida
Aucune des options --nullou -n1n'est disponible sur OSX
Valeriy Van
1

Et ça:

find … | egrep -o -e '[^/]+$'

Avantage: un seul processus supplémentaire est généré, pas un pour chaque résultat.

David Foerster
la source
0

Vous pouvez appeler shdepuis l' -execoption find et éviter d'utiliser des tuyaux inutiles. Cela a également l'avantage de ne pas vous soucier des noms de fichiers amusants (espaces, nouvelles lignes, etc.):

find . -type f -exec sh -c 'echo "${0##*/}"' {} \;
evilsoup
la source