Como "grep" para um nome de arquivo em vez do conteúdo de um arquivo?

135

grep é usado para pesquisar em um arquivo para ver se alguma linha corresponde a uma determinada expressão regular. No entanto, eu tenho essa situação - quero escrever uma expressão regular que corresponda ao próprio nome do arquivo (e não ao conteúdo do arquivo). Vou executar isso no diretório raiz do sistema, para encontrar todos os arquivos que correspondem à expressão regular.

Por exemplo, se eu quiser encontrar todos os arquivos de formulário VB que começam com "f" e terminam com .frm, usarei a expressão regular -

   "f[[:alnum:]]*\.frm"

O grep pode fazer isso? Caso contrário, existe algum utilitário que me permita fazer isso? Obrigado.

Código Azul
fonte

Respostas:

120

Você precisa usar em findvez de grepneste caso.

Você também pode usar findem combinação com grepou egrep:

$ find | grep "f[[:alnum:]]\.frm"
Pablo Santa Cruz
fonte
12
Isso é desnecessário. O Find possui essa funcionalidade integrada com a -regexopção
whereswalden
4
aqui é desnecessário, mas o grep suporta perl regex, enquanto o find não.
Dan
2
Não, você pode usar grep. Muito mais fácil do que usar o find. Adicione a opção "-rl" e ele pesquisará o nome do arquivo em vez do arquivo. Veja meu post abaixo.
RM
@ alpha_989, eu disse que o grep suporta, o que faz: gnu.org/software/grep/manual/html_node/… point is piping to grep só é necessário se você precisar de pcre. whereswalden tem a resposta certa
Dan
60

Exemplo

find <path> -name *FileName*

Do manual:

padrão find -name

A base do nome do arquivo (o caminho com os diretórios principais removidos) corresponde ao padrão do padrão de shell. Como os diretórios principais são removidos, os nomes de arquivos considerados para uma correspondência com -name nunca incluirão uma barra, portanto, "-name a / b" nunca corresponderá a nada (você provavelmente precisará usar -path). Os metacaracteres ("*", "?" E "[]") correspondem a um "." no início do nome da base (esta é uma alteração nos achados utilitários-4.2.2; consulte a seção CONFORMIDADE PADRÕES abaixo). Para ignorar um diretório e os arquivos nele, use -prune; veja um exemplo na descrição de -path. Os aparelhos não são reconhecidos como especiais, apesar de algumas conchas, incluindo o Bash, atribuírem um significado especial aos padrões de conchas. A correspondência do nome do arquivo é realizada com o uso da função de biblioteca fnmatch (3). Não se esqueça de colocar o padrão entre aspas para protegê-lo da expansão pelo shell.

javaPlease42
fonte
2
Achei esta resposta a mais útil. Adicionei algumas opções adicionais: find . -maxdepth 1 -name "*filename*" -print
JSON C11
47

Como disse Pablo, você precisa usar find, em vez de grep, mas não há nenhuma necessidade de tubulação findpara grep. findtem essa funcionalidade incorporada:

find . -regex 'f[[:alnum:]]\.frm'

findé um programa muito poderoso para pesquisar arquivos por nome e suporta pesquisa por tipo de arquivo, limitação de profundidade, combinação de termos de pesquisa diferentes com operações booleanas e execução de comandos arbitrários nos arquivos encontrados. Consulte a página do manual find para obter mais informações.

whereswalden
fonte
1
Gostaria de acrescentar o recurso muito útil de localização para pesquisar por data -mtimee-mmin
Johnride
1
Além disso, a opção -regex executa correspondências com todo o caminho. Portanto, para trabalhar, o exemplo precisa adicionar. * No início da regex.
tumasgiu
15

Você pode encontrar o caminho completo de um arquivo usando grep, apenas canalize a saída da árvore

tree -f | grep filename

Aqui está uma função que você pode colocar no seu .bash_profile ou .bashrc

findfile(){ tree -f | grep $1; } # $1 = filename, -f is full path
jasonleonhard
fonte
-f é opcional.
jasonleonhard
10
find -iname "file_name"

Syntax :-
find -type type_descriptor file_name_here

type_descriptor tipos: -

f: arquivo regular

diretório d:

l: link simbólico

c: dispositivos de caracteres

b: bloquear dispositivos

Sireesh Yarlagadda
fonte
1
Eu não consigo usar um nome de arquivo após o -type typedescriptorsozinho. Isso é um erro?
Allan Nørgaard
5

Você também pode fazer:

tree | grep filename

Isso canaliza a saída do comando tree para grep para uma pesquisa. Isso apenas informa se o arquivo existe.

caylus
fonte
1

Não, o grep funciona bem para isso:

 grep -rl "filename" [starting point]

 grep -rL "not in filename"
RM
fonte
1
Ele pesquisa o conteúdo do arquivo por "nome do arquivo" e imprime os nomes dos arquivos com correspondências. O OP deseja combinar nomes de arquivos, não conteúdos.
Matthew
1
Concordado, isso não pesquisa nomes de arquivos, apenas imprime os nomes dos nomes de arquivos com os quais o conteúdo encontrado corresponde. Você entendeu mal as opções -le -Lconsideravelmente.
Prometheus
2
+1 por ser exatamente o que eu preciso. Feliz eu não tenho de criticar a questão de encontrar a resposta que eu precisava
Alexander McNulty
-1

Também para vários arquivos.

tree /path/to/directory/ | grep -i "file1 \| file2 \| file3"
DimiDak
fonte
-1

A maneira mais fácil é

find . | grep test

aqui find listará todos os arquivos no diretório atual (.) ou seja, recursivamente. E então é apenas um grep simples. todos os arquivos cujo nome tem "teste" aparecerão.

você pode jogar com grep conforme sua exigência. Nota: Como o grep é uma classificação genérica de cadeias, pode resultar em fornecer não apenas nomes de arquivos. mas se um caminho tiver um diretório ('/xyz_test_123/other.txt') também chegará ao conjunto de resultados. Felicidades

sachyy
fonte
Isso encontrará qualquer coisa com "teste" no caminho, por exemplo ./foo/bar/latest/fred.txt.
Paul R
ah Aquele em que não pensei. Obrigado por mencionar.
sachyy 6/06