Comment sortir le nom de fichier dans la commande find en utilisant -exec?

33

J'utilise la ligne suivante pour trouver tous les sous-répertoires de la PWD et les exécuter svnadmin verifysur chaque répertoire (je sais déjà qu'il s'agit de référentiels Subversion)

find ./* -maxdepth 0 -exec svnadmin verify {} \;

Cela fonctionne bien, à part le fait que la sortie ressemble à ceci:

* Verifying repository metadata ...
* Verifying metadata at revision 1 ...
* Verifying metadata at revision 2 ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 9 ...
* Verifying metadata at revision 10 ...
* Verifying metadata at revision 12 ...
* Verifying metadata at revision 14 ...
* Verifying metadata at revision 15 ...
* Verifying metadata at revision 18 ...
* Verifying metadata at revision 20 ...
* Verifying metadata at revision 22 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.
* Verified revision 10.
* Verified revision 11.
* Verified revision 12.
* Verified revision 13.
* Verified revision 14.
* Verified revision 15.
* Verified revision 16.
* Verified revision 17.
* Verified revision 18.
* Verified revision 19.
* Verified revision 20.
* Verified revision 21.
* Verified revision 22.
* Verified revision 23.
* Verified revision 0.
* Verifying repository metadata ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 7 ...
* Verifying metadata at revision 9 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.

J'aimerais vraiment findimprimer le nom de fichier avant d'exécuter la svnadmin verifycommande pour faciliter la journalisation.

J'ai essayé de me faufiler un peu lslà-dedans, mais je l'ai fait, comment dois-je faire cela (de préférence simplement)?

Arronique
la source

Réponses:

36

ajoutez simplement une -printfoption avant

find -printf '%p' -exec command \;
Fiximan
la source
4
Charmant, j'ai changé '%p'pour '%p\n'que le nom précède la sortie de vérification sur sa propre ligne.
Arronical
17
@Arronical Si c'est le format que vous voulez, vous pouvez remplacer le (formaté) -printf '%p\n'par le plus simple-print
steeldriver
4
find -name <a_name> -print -exec command {} \;
toliveira
14

Si vous ne voulez pas recurse, il n'y a aucun intérêt à utiliser find. C'est beaucoup plus simple de le faire directement dans le shell:

for d in */; do echo "$d"; svnadmin verify "$d"; done

Le for d in */trouvera tous les répertoires ( */assure que seuls les répertoires et aucun fichier ne sont trouvés); le echo "$d"va imprimer le nom du répertoire; le svnadmin verify "$d"vérifiera le répertoire.

Cela peut être exécuté directement à partir de la ligne de commande ou à l'intérieur d'un script sans changement de format.

terdon
la source
1
Cela semble être un meilleur moyen d'atteindre mon objectif, mais je devais donner la réponse à Fiximan simplement parce que mon titre et ma question faisaient findbeaucoup référence . Merci d'avoir amélioré mes connaissances!
Arronical
Cela nécessite l'utilisation d'un glob. Globbing est certainement utile et puissant, mais selon mon expérience personnelle, la syntaxe est plus difficile à configurer et finit souvent par nécessiter d'autres éléments tels que dotglobet globstaren bash, ce qui crée un script plus long et plus compliqué. J'ai tendance à sauvegarder des globs pour des tâches complexes et volumineuses, alors que findla syntaxe est plus facile à combiner à la volée en enchaînant simplement un tas de filtres et de commandes dans une seule ligne.
user5359531
@ user5359531 ni globstar ni dotglob (sauf si vous savez que vous avez caché des fichiers et que vous les voulez réellement) sont nécessaires ici. C’est évidemment une question d’opinion, mais vous êtes la première personne que je connaisse qui considère le format plutôt obtus du findplus simple. Je préfère toujours les globs, findcar non seulement je les trouve beaucoup plus simples, mais ils sont également plus sûrs lorsqu'il s'agit de noms de fichiers arbitraires transmis à d'autres programmes.
Terdon
6
find ./* -maxdepth 0 -type d -exec bash -c 'echo "{}"; svnadmin verify "{}"' \;

J'ai ajouté -type ds'il s'agit uniquement de répertoires.

7171u
la source
Je cite {}, au moins danssvnadmin verify {}
kos
Merci pour la réponse rapide. Donc, dans cette commande, le -execspawn est-il un shell enfant, dans lequel les 2 commandes sont exécutées, utilisant ;comme fin de ligne?
Arronical
5

Essaye ça:

for f in * ; do echo  -n "${f}:"; svnadmin verify "${f}"; done

Si vous voulez juste des répertoires (Merci à @kos note):

for f in */ ; do echo  -n "${f}:"; svnadmin verify "${f}"; done
Maythux
la source
Bien, mais cela traitera aussi les fichiers: for f in */ne traitera que les répertoires
kos
Cela fonctionnera-t-il uniquement dans un script? Ou puis-je le publier sur la ligne de commande?
Arronical
1
@Arronical fonctionnera également en ligne de commande
Maythux le
2
  • Utilisez . -maxdepth 1au lieu de ./*, vous n'avez besoin que du premier niveau de la structure de dossiers
  • Utilisez -type d, vous n'avez besoin que de dossiers
  • Utilisez ! -name ".", vous n'avez pas besoin.
  • Utiliser -execpour démarrer un shell
  • Utiliser sh -cpour lancer des commandes à l'intérieur du shell

Votre commande

find . -maxdepth 1 -type d ! -name "." -exec sh -c 'echo "{}"; svnadmin verify "{}"' \;

ou plus court

  • Utilisez -prunesi le fichier est un répertoire, n'y descendez pas

Votre commande

find . -mindepth 1 -prune -exec sh -c 'echo "{}"; svnadmin verify "{}"' \; 
UN B
la source
-prunesemble intéressant. J'avais l'habitude ./* -maxdepth 0d'éviter de revenir .de la commande find. Cela ne cause aucune erreur critique, mais je préfère ne pas l'avoir dans mes résultats.
Arronical
1

findpossède des options pour l’impression, déjà mentionnées dans d’autres réponses. Si nous examinons le problème sous la perspective d’exécuter plusieurs commandes pour le même fichier en cours de traitement, findpermet d’utiliser plusieurs -execinstructions. Cela signifie que nous pourrions choisir d'utiliser:

find ./* -maxdepth 0 -exec echo {} \; -exec svnadmin verify {} \; 

Encore une fois, notez que cette approche est applicable non seulement avec l' impression echo, printfou d' autres services publics, mais aussi d' autres commandes.

Sergiy Kolodyazhnyy
la source
0

Il peut être utile de diriger la findsortie vers une readboucle:

find . | while read d; do echo "=== ${d}: ==="; svnadmin verify ${d}; done

Il vous permet d'exécuter une séquence de commandes composée plus complexe avec les noms de fichiers renvoyés par find, comme dans cet lsexemple sophistiqué :

find . | while read f; do echo ${f} | figlet -k; done
Ves
la source
-1

Ceci imprimera le nom et le contenu des fichiers uniquement de manière récursive.

find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Prashant Adlinge
la source