web-dev-qa-db-fra.com

Comment utiliser regex avec la commande find?

J'ai des images nommées avec la chaîne générée uuid1. Par exemple, 81397018-b84a-11e0-9d2a-001b77dc0bed.jpg. Je veux trouver toutes ces images en utilisant la commande "find":

find . -regex "[a-f0-9\-]\{36\}\.jpg".

Mais ça ne marche pas. Quelque chose ne va pas avec la regex? Est-ce que quelqu'un pourrait m'aider avec ça?

251
thoslin
find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"

Notez que vous devez spécifier .*/ au début car find correspond à tout le chemin.

Exemple:

susam@nifty:~/so$ find . -name "*.jpg"
./foo-111.jpg
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.jpg"
./test/81397018-b84a-11e0-9d2a-001b77dc0bed.jpg
./81397018-b84a-11e0-9d2a-001b77dc0bed.jpg

Ma version de trouver:

$ find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=0) 
susam@nifty:~/so$ 
susam@nifty:~/so$ find . -regextype foo -regex ".*/[a-f0-9\-]\{36\}\.jpg"
find: Unknown regular expression type `foo'; valid types are `findutils-default', `awk', `egrep', `ed', `emacs', `gnu-awk', `grep', `posix-awk', `posix-basic', `posix-egrep', `posix-extended', `posix-minimal-basic', `sed'.
298
Susam Pal

L'expression de recherche -regex correspond au nom complet, y compris le chemin relatif du répertoire en cours. Pour find ., cela commence toujours par ./, puis tous les répertoires.

En outre, il s’agit de emacs expressions rationnelles, qui ont d’autres règles d’échappement que les expressions régulières egrep habituelles.

Si ceux-ci sont tous directement dans le répertoire en cours, alors

find . -regex '\./[a-f0-9\-]\{36\}\.jpg'

devrait marcher. (Je ne suis pas vraiment sûr - je ne peux pas faire fonctionner la répétition comptée ici.) Vous pouvez passer aux expressions egrep de -regextype posix-egrep:

find . -regextype posix-egrep -regex '\./[a-f0-9\-]{36}\.jpg'

(Notez que tout ce qui est dit ici concerne GNU find, je ne connais rien du système BSD, qui est également celui par défaut sur Mac.)

72
Paŭlo Ebermann

À en juger par les autres réponses, il semble que ce soit peut-être la faute de find.

Cependant, vous pouvez le faire de cette façon:

find . * | grep -P "[a-f0-9\-]{36}\.jpg"

Vous devrez peut-être modifier légèrement le grep et utiliser différentes options en fonction de ce que vous voulez, mais cela fonctionne.

29
yarian

Essayez d’utiliser des guillemets simples (') pour éviter que Shell n’échappe à votre chaîne. N'oubliez pas que l'expression doit correspondre à l'intégralité du chemin, c'est-à-dire qu'elle doit ressembler à:

 find . -regex '\./[a-f0-9-]*.jpg'

En dehors de cela, il semble que ma découverte (GNU 4.4.2) ne connaisse que les expressions rationnelles de base, en particulier la syntaxe {36}. Je pense que vous devrez vous en passer.

7
thiton

Manière simple - vous pouvez spécifier. * Au début car trouver correspond à tout le chemin.

$ find . -regextype egrep -regex '.*[a-f0-9\-]{36}\.jpg$'

trouver la version

$ find --version
find (GNU findutils) 4.6.0
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION 
FTS(FTS_CWDFD) CBO(level=2)
7
binbjz

Vous devez utiliser le chemin de répertoire absolu lors de l'application d'une instruction de recherche avec une expression régulière. Dans votre exemple, le

find . -regex "[a-f0-9\-]\{36\}\.jpg"

devrait être changé en

find . -regex "./[a-f0-9\-]\{36\}\.jpg"

Dans la plupart des systèmes Linux, certaines disciplines des expressions régulières ne peuvent pas être reconnues par ce système. Vous devez donc indiquer explicitement -regexty comme

find . -regextype posix-extended -regex "[a-f0-9\-]\{36\}\.jpg"
6
Lovely

sous Mac OS X (recherche BSD): Identique à la réponse acceptée, le préfixe .*/ est nécessaire pour faire correspondre un chemin complet:

$ find -E . -regex ".*/[a-f0-9\-]{36}.jpg"

man find dit -E utilise le support regex étendu

4
Stan Kurdziel