Como usar o regex com o comando find?

298

Eu tenho algumas imagens nomeadas com a string uuid1 gerada. Por exemplo 81397018-b84a-11e0-9d2a-001b77dc0bed.jpg. Quero descobrir todas essas imagens usando o comando "find":

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

Mas isso não funciona. Algo errado com a regex? Alguém poderia me ajudar com isso?

thoslin
fonte
7
talvez mude o regextype. O padrão é Expressões regulares do Emacs , o que quer que isso signifique.
pavium 27/07

Respostas:

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

Observe que você precisa especificar .*/no início porque findcorresponde ao caminho inteiro.

Exemplo:

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

Minha versão do find:

$ 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'.
Susam Pal
fonte
4
@ Tom é o modo como o regex em find funciona. De acordo com a página do manual, o regex corresponde ao caminho completo do arquivo, incluindo os diretórios, o que significa que há um implícito em "^ ... $"torno do regex. Ele deve corresponder à linha de resultado INTEIRA.
Manny D
2
Eu não acho que você precisa do /em .*/causa .*corresponde a zero ou mais de (quase) qualquer personagem.
10243 Jeff
2
Para aqueles (como eu) que não leu o regex corretamente primeira vez: Observe as barras invertidas anteriores caracteres especiais regex, por exemplo:\{36\}
Lucas Wilson-Richter
11
Eu tive problemas para encontrar a lista completa de tipos de expressões regulares (a página de manual não está atualizada):valid types are 'findutils-default', 'awk', ' egrep', 'ed', 'emacs', 'gnu-awk', 'grep', 'posix-awk', 'posix-basic', 'posix-egrep', 'posix -extended', 'posix-minimal-basic', 'sed'.
Noah Sussman
4
Certifique-se de colocar a -regextypebandeira antes da -regexbandeira, caso contrário ela não se aplica!
Christopher Orr
84

A -regexexpressão find corresponde ao nome inteiro , incluindo o caminho relativo do diretório atual. Para find .isso sempre começa com ./, em seguida, quaisquer diretórios.

Além disso, essas são emacsexpressões regulares, que possuem outras regras de escape além das expressões regulares usuais do egrep.

Se todos estiverem diretamente no diretório atual,

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

Deveria trabalhar. (Não tenho muita certeza - não posso fazer com que a repetição contada funcione aqui.) Você pode alternar para expressões egrep -regextype posix-egrep:

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

(Observe que tudo o que foi dito aqui é para encontrar o GNU, não sei nada sobre o BSD, que também é o padrão no Mac.)

Paŭlo Ebermann
fonte
1
Eu tinha parênteses para várias seqüências correspondentes no meu regex, portanto, o posix-egreptipo funcionou para mim.
precisa saber é o seguinte
2
Algo a notar, -regextypeé uma opção para o GNU finde não para o BSD (pelo menos não para o Mac BSD) find. Se esta opção não estiver disponível, instale o GNU find. Se em um Mac, isso é possível com o pacote de preparação findutils. Localizar fica disponível via gfind.
DanCat 10/10
O regextype posix-egrep fez a tarefa por mim. Eu acho que o padrão é regextype emacs.
infoclogou em 11/01/19
35

A julgar por outras respostas, parece que isso pode ser culpa do achado.

No entanto, você pode fazer desta maneira:

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

Talvez você precise ajustar um pouco o grep e usar opções diferentes, dependendo do que você deseja, mas ele funciona.

yarian
fonte
Funcionou bem para mim e oferece um grande grau de liberdade em relação à regex.
Glaucon
3
A desvantagem com isso é que você não pode tirar proveito de find's -prunefuncionalidade que irá saltar sobre certos diretórios completamente. Na maioria das vezes isso não é realmente importante, mas vale a pena mencionar.
Alexander Bird
-A poda ainda vai funcionar, eu acho. Seria mais perigoso usar -exec - seria executado em todos os arquivos e não apenas naqueles que o grep permite passar.
tpb261 14/04
13

no Mac OS X (localização BSD) : igual à resposta aceita, o .*/prefixo é necessário para corresponder a um caminho completo:

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

man finddiz que -Eusa suporte estendido a regex

Stan Kurdziel
fonte
Parece que -Enão está disponível no Ubuntu (testado no WSL Ubuntu)
Warlike Chimpanzee
2
@Clever Little Monkey - Não, a resposta aceita deve funcionar no Ubuntu, esta variação é para Mac OS X especificamente (ou talvez uma outra variante BSD como FreeBSD)
Stan Kurdziel
8

Tente usar aspas simples (') para evitar que o shell escape da sua string. Lembre-se de que a expressão precisa corresponder a todo o caminho, ou seja, precisa se parecer com:

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

Além disso, parece que meu achado (GNU 4.4.2) conhece apenas expressões regulares básicas, especialmente a sintaxe {36}. Eu acho que você terá que se contentar sem isso.

thiton
fonte
8

Maneira simples - você pode especificar. * No início porque find corresponde a todo o caminho.

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

encontrar versão

$ 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)
binbjz
fonte
6

Você deve usar o caminho absoluto do diretório ao aplicar a instrução find com expressão regular. No seu exemplo, o

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

deve ser alterado para

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

Na maioria dos sistemas Linux, algumas disciplinas de expressão regular não podem ser reconhecidas por esse sistema; portanto, você deve indicar explicitamente

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