Est-il possible d'obtenir des backticks de développement "find -exec" pour chaque fichier trouvé?

9

Voici une commande qui fonctionne bien:

echo Blah: `stat -c %a .`

Est-il possible d' find -execexécuter cette même chose pour chaque fichier trouvé, avec {}à la place de .?

RomanSt
la source
1
Les backticks ne peuvent pas y fonctionner car ils sont évalués une fois avant d' findêtre même exécutés et le résultat est utilisé comme paramètre statique pour la recherche.
Sven

Réponses:

10

La meilleure façon de le faire est d'utiliser des paramètres de position. Et $()est préféré pour la substitution de commandes au-dessus des astuces car il est plus lisible (n'est pas confondu avec des guillemets simples) et peut être facilement imbriqué sans avoir à faire beaucoup d'échappement.

find . -exec bash -c 'echo Blah: $(stat -c %a "$@")' _ {} \;

Le trait de soulignement est un espace réservé pour $0.

En pause jusqu'à nouvel ordre.
la source
6

Pourquoi?

find ... -printf 'Blah: %m\n'

Ou utilisez bash -csi vous devez vraiment:

 find . -exec bash -c 'echo Blah: `stat -c %a {}`' \;
Ignacio Vazquez-Abrams
la source
Merci d'avoir résolu mon problème immédiat, mais je suis toujours curieux de savoir si les astuces peuvent être utilisées comme décrit. Juste pour élargir mes horizons.
RomanSt
Vous devez invoquer le shell via bash -cou similaire.
Ignacio Vazquez-Abrams
0

La seule façon de les utiliser (AFAIK) est de les placer dans un fichier de script bash et d'utiliser le script dans -exec. Même chose avec$()

Hubert Kario
la source
0

N'oubliez pas xargs! Votre exemple invoquerait un nouveau processus shell pour chaque fichier trouvé.

Je préfère ceci:

find ... | xargs stat -c "Blah: %a"

findaffiche une liste de tout ce qui a été trouvé, xargslit une liste d'arguments stdinet exécute son paramètre avec ces arguments sur la ligne de commande, créant une ligne de commande aussi longue que possible. Cela fonctionne parce que stat, comme la plupart des autres commandes / programmes appropriés, prennent n'importe quel nombre de paramètres. (comparer ls, rmet echopar exemple)

Si vous pensez qu'il est absolument nécessaire de lancer un nouveau processus pour chaque fichier, utilisez xargs -n 1uniquement pour passer des 1paramètres à chaque commande. De cette façon, vous pouvez imiter les méthodes inefficaces comme ceci:

find ... | xargs -n 1 stat -c "Blah: %a"

(Essayez-le sur un gros système de fichiers sur un ordinateur lent et chronométrez les différences!)

MattBianco
la source
J'apprécie l'effort, mais j'ai besoin de ces astuces. Évidemment, mon exemple est simplifié et utilise echo + stat; le vrai script n'utilise ni écho ni stat, donc votre astuce de les assembler dans la chaîne de format de stat n'aide pas du tout.
RomanSt