Como posso encontrar todos os arquivos em uma pasta que contenham uma correspondência de uma expressão regular no nome do arquivo?

3

Gostaria de encontrar todos os arquivos em minha pasta pessoal no Linux (Ubuntu, neste caso) que contêm uma correspondência com uma expressão regular específica. Existe um comando simples do Unix que eu possa usar para fazer isso?

Por exemplo, eu gostaria de encontrar todos os arquivos em minha pasta pessoal com nomes que contenham uma correspondência da seguinte regex (aqui, usando a notação em estilo Javascript): ((R|r)eading(T|t)est(D|d)ata)

    
por Anderson Green 26.08.2012 / 06:56

4 respostas

2

Os shells têm caracteres curinga que diferem das sintaxes usuais de expressão regular: ? para corresponder a qualquer caractere único, * para corresponder a qualquer número de caracteres e [abc] para corresponder a qualquer caractere único entre a , b ou c . O comando a seguir mostra todos os arquivos cujo nome corresponde à expressão regular estendida¹ ((R|r)eading(T|t)est(D|d)ata) no diretório atual:

echo *[Rr]eading[Tt]est[Dd]ata*

Se você quiser encontrar arquivos em subdiretórios, execute primeiro shopt -s globstar (você pode colocar este comando em ~/.bashrc ). Isso ativa o padrão ** para corresponder a qualquer nível de subdiretórios:

echo **/*[Rr]eading[Tt]est[Dd]ata*

Os caracteres curinga da shell não são tão poderosos quanto as expressões regulares. Por exemplo, não há ou ( | ) operador. Você pode obter o poder das expressões regulares, mas com uma sintaxe diferente por motivos históricos. Adicione shopt -s exgblob ao seu .bashrc , então você pode usar @(foo|bar) para corresponder a foo ou bar (como foo|bar em um ERE), *(pattern) para corresponder a uma sequência qualquer número de ocorrências de pattern (como (pattern)* em um ERE), +(pattern) para corresponder a uma ou mais ocorrências, ?(pattern) para corresponder a zero ou uma ocorrência e !(pattern) para corresponder a qualquer coisa, exceto pattern (sem equivalente ERE). p>

¹ “Expressão regular estendida” (ERE abreviado) é o nome do unix da sintaxe de regex que o JavaScript usa.

    
por 27.08.2012 / 00:08
2

A opção -name do Find suporta globulação de arquivos. Ele também suporta um conjunto limitado de opções semelhantes ao regex, como expressões de colchetes limitados, mas para correspondências reais de regex, use -regex .

Se você estiver procurando uma correspondência no conteúdo de um arquivo, use grep -r como Craig sugeriu.

Se você quiser corresponder o nome do arquivo, use find com sua opção -regex :

find . -type f -regex '.*[Rr]eading[Tt]est[Dd]ata.*' -print

Observe a mudança na regex, porque find não suporta portably entre átomos em sua regex. Se você estiver em um sistema Linux, o GNU find suporta uma opção -regextype que lhe dá mais controle:

find . -regextype posix-extended -regex '.*((R|r)eading(T|t)est(D|d)ata).*' -print

Observe que, se tudo o que você está procurando for uma correspondência de caso, -iregex ou mesmo -iname poderá ser suficiente. Se você está usando bash como sua concha, a solução globstar da Gilles deve funcionar também.

    
por 27.08.2012 / 13:48
1

grep tem uma opção -r recursiva, que pesquisará todos os arquivos em todos os subdiretórios pelo padrão.

A opção -l apenas lista os arquivos que contêm o padrão. Se você quiser uma contagem de correspondências em cada arquivo, use -c e, se quiser ver as correspondências, não use -l ou -c.

  1. (R|r) é apenas uma maneira detalhada de escrever [Rr] . também é mais lento que uma classe (mas não o suficiente para importar, a menos que esteja em um loop que seja executado milhões de vezes):

    grep -lr '[Rr]eading[Tt]est[Dd]ata' ~/

  2. Completamente insensível a maiúsculas e minúsculas:

    grep -lir 'readingtestdata' ~/

  3. se você quiser apenas pesquisar arquivos em ~, mas não em subdiretórios, use find :

    find ~/ -maxdepth 1 -type f -print0 | xargs -0r grep -l '[Rr]eading[Tt]est[Dd]ata'

por 26.08.2012 / 07:27
0

Você pode simplesmente passar seu padrão para encontrar:

$ find . -type f  -name "[Rr]eading[Tt]est[Dd]ata*"

Para o padrão específico na pergunta, você pode simplesmente usar a diferenciação entre maiúsculas e minúsculas:

$ find . -type f -iname readingtestdata
    
por 27.08.2012 / 13:17