2010-09-20 5 views
1

Je voudrais faire quelque chose comme:bash: Test complexe commande find

find . -type f -exec test $(file --brief --mime-type '{}') == 'text/html' \; -print 

, mais je ne peux pas comprendre la manière correcte de citer ou échapper aux args pour tester, en particulier les « $ (» ... ')'.

Répondre

9

Vous ne pouvez pas simplement échapper les arguments pour les transmettre à find.

Toute expansion de l'interpréteur de commandes va se produire avant d'exécuterfind. find ne passera pas ses arguments à travers un shell, donc même si vous échappez à l'expansion du shell, tout sera simplement traité comme des arguments littéraux à la commande test, pas développé par le shell comme vous l'attendez.

La meilleure façon d'obtenir ce que vous voulez serait d'écrire un script shell, qui prend le nom de fichier comme argument, et utiliser -exec sur ce point:

find . -type f -exec is_html.sh {} \; -print 

avec is_html.sh:

#!/bin/sh 

test $(file --brief --mime-type "$1") == 'text/html' 

Si vous voulez vraiment tout sur une ligne, sans utiliser un script séparé, vous pouvez appeler sh directement à partir de find:

find . -type f -exec sh -c 'test $(file --brief --mime-type "$0") == "text/html"' {} \; -print 
+0

J'avais peur que ce soit la réponse! J'essaie d'éviter de créer un script de commande séparé juste pour le test. Cela semble fonctionner aussi: 'trouver. -type f -exec fichier --mime-type '{}' \; | grep 'text/html' | couper -d ':' -f1', mais j'espérais une solution plus générale à ce genre de pattern. –

+0

Vous pouvez également utiliser l'option -c de bash au lieu d'écrire le code dans un fichier séparé: find. -type f -exec bash -c 'test $ (fichier --brief --mime-type "$ 1") == "text/html"' '' {} \; -print –

+0

@Bart Oui, vous pouvez tout mettre en ligne en invoquant 'bash' ou' sh' directement; Je pensais qu'il serait plus clair d'utiliser un fichier distinct, mais vous avez raison, si vous voulez vraiment tout mettre sur une ligne, vous pouvez le faire. –

1

Bien qu'il puisse être possible de le transformer en une déclaration citée d'une manière extravagante, il est souvent plus facile - et plus clair - être un peu plus bavard:

$ find . -type f -print0 | xargs -0 file --mime-type | ↷ 
    grep ':[^:]*text/html$'| sed 's,:[^:]*text/html,,' 
0

Utilisez « {} » au lieu, pour un exemple ceci énumère simplement les types de dossier:

find * -maxdepth 0 -exec file "{}" \;