Como encontrar um arquivo no sistema de arquivos a partir da linha de comando?

10

Gostaria de encontrar um arquivo (com um nome de arquivo parcialmente conhecido) no sistema de arquivos. Gostaria de saber como fazer isso a partir da linha de comando, em vez de usar um utilitário de GUI.

No Windows, eu corria o seguinte:

cd /d C:\
dir *filename* /s

Qual é o equivalente do Linux?

    
por Iszi 16.11.2011 / 03:15

4 respostas

12
locate filename
find -name '*filename*'
echo **/*filename*
ls -ld **/*filename*

(Leia sobre os principais termos e condições. Leia o manual para a boa impressão.)

Listar o conteúdo de um diretório é uma característica secundária de ls . O principal trabalho de ls , aquele que ocupa a maior parte de sua complexidade, está ajustando sua exibição. (Consulte o manual e compare o número de opções relacionadas à escolha de quais arquivos exibir versus o número de opções que controlam quais informações exibir sobre cada arquivo e como a exibição é formatada. Isso é verdadeiro para GNU ls que você encontrará no Linux, e de outros sistemas com menos opções, já que o cedo dias.)

O modo padrão de ls é que, quando você passa a ele um diretório, ele lista os arquivos nesse diretório. Se você passar qualquer outro tipo de arquivo (arquivo regular, link simbólico etc.), ele listará apenas esse arquivo. (Isso se aplica a cada argumento separadamente.) A opção -d diz ls para nunca descer em um diretório.

ls tem uma opção -R que diz para listar os diretórios recursivamente. Mas é de aplicabilidade limitada e não permite muita filtragem na saída.

A primeira ferramenta para realizar correspondência de padrões é o próprio shell. Você não precisa de nenhum outro comando: basta digitar seus curingas e está pronto. Isso é conhecido como globbing .

echo *filename*

Tradicionalmente, os curingas eram limitados ao diretório atual (ou ao diretório indicado: echo /some/where/*filename* ). Um * corresponde a qualquer nome de arquivo ou a qualquer parte do nome do arquivo, mas *.txt não corresponderá a foo/bar.txt . Os shells modernos adicionaram o padrão **/ , que significa “neste diretório, ou em qualquer diretório abaixo dele (recursivamente)”. Com o bash, por motivos de compatibilidade histórica, esse recurso precisa ser ativado explicitamente com shopt -s globstar (você pode colocar essa linha em ~/.bashrc ).

echo **/*filename*

O comando echo apenas ecoa a lista de nomes de arquivos gerados pelo shell de volta para você. Como uma exceção, se não houver nenhum nome de arquivo correspondente, o padrão de caractere curinga é mantido inalterado no bash (a menos que você defina shopt -s nullglob , caso em que o padrão se expande para uma lista vazia) e zsh sinaliza um erro (a menos que você defina setopt nullglob ou setopt no_no_match , o que faz com que o padrão seja deixado inalterado).

Você ainda pode querer usar ls para suas opções. Por exemplo, ls pode fornecer indicações sobre a natureza ou as permissões do arquivo (diretório, executável, etc.) por meio das cores. Você pode querer exibir a data, tamanho e propriedade do arquivo com ls -l . Veja o manual para muitas outras opções.

O comando tradicional para procurar um arquivo em uma árvore de diretórios é find . Ele vem com muitas opções para controlar quais arquivos exibir e o que fazer com eles. Por exemplo, para procurar arquivos cujo nome corresponda ao padrão *filename* no diretório atual e seus subdiretórios e imprima seus nomes:

find /some/dir -name '*filename*' -print

-print é uma ação (a maioria das outras ações consiste em executar um comando no arquivo); se você não colocar uma ação, -print está implícito. Além disso, se você não especificar nenhum diretório para percorrer ( /some/dir acima), o diretório atual estará implícito. A condição -name '*filename' diz para listar (ou atuar) apenas os arquivos cujo nome corresponde a esse padrão; Há muitos outros filtros, como -mtime -1 para corresponder aos arquivos modificados nas últimas 24 horas. Às vezes, você pode omitir as aspas em -name '*filename*' , mas apenas se o caractere curinga não corresponder a nenhum arquivo no diretório atual (veja acima). Em suma, a forma abreviada é

find -name '*filename*'

Outra ferramenta útil quando você sabe (parte de) o nome de um arquivo é locate . Essa ferramenta consulta um banco de dados de nomes de arquivos. Em sistemas típicos, é atualizado a cada noite. A vantagem de locate over find / é que é muito mais rápido. Uma desvantagem é que suas informações podem estar obsoletas. Existem várias implementações de locate que diferem em seu comportamento em sistemas multiusuário: o programa básico locate indexa apenas arquivos legíveis publicamente (você pode querer executar o complemento updatedb para criar um segundo banco de dados que indexe todos os arquivos em sua conta); existem outras versões (mlocate, slocate) que indexam todos os arquivos e têm o programa locate filtrando o banco de dados para retornar apenas os arquivos que você pode ver.

locate filename

Às vezes você acha que um arquivo é fornecido por um pacote em sua distribuição, você sabe (parte de) o nome do arquivo, mas não o nome do seu pacote, e gostaria de instalar o pacote. Muitas distribuições fornecem uma ferramenta para isso. No Ubuntu, é apt-file search filename . Para comandos equivalentes em outros sistemas, verifique o Pacman Rosetta .

    
por 16.11.2011 / 23:11
6

o equivalente ao seu exemplo do DOS seria:

cd /
find . -name \*filename\* -print

No Linux, você geralmente não precisa mais do argumento -print . Se você se encontrar trabalhando em outros sistemas operacionais, pode ser útil conhecê-lo.

    
por 16.11.2011 / 03:36
5

Se você quiser algo "rápido" , mas não em uma situação de missão crítica e desejar apenas saber se ele existe e onde está, use locate . Ele mantém um banco de dados de todos os arquivos nos diretórios que você informou para coletar informações.

Na instalação padrão (no Ubuntu), locate configura uma tarefa diária de cron que varre o sistema de arquivos e atualiza o banco de dados ...

Se você acha que precisa atualizar o banco de dados antes da próxima atualização do cron, é mais rápido que find ou ls executar apenas sudo updatedb e, em seguida, locate . É definitivamente mais rápido se você precisar fazer mais pesquisas ... como o nome sugere, updatedb atualiza o banco de dados que locate usa ...

locate tem regex incorporada, o que torna muito útil ... Usarei find em um script, mas raramente uso find na linha de comando. Eu até uso locate em scripts (pessoais) ... por exemplo. locate -bir "oo.*datt.*mp4$"

locate retorna os caminhos completos dos arquivos correspondentes.

    
por 16.11.2011 / 05:55
2
find [path] -name [filename]

Por exemplo, se eu quiser pesquisar no diretório / home um nome de arquivo contendo foo, usaria o comando:

find /home -name *foo*

use o comando man find para mais informações sobre o comando find e argumentos,

    
por 16.11.2011 / 03:36