Como encontrar um arquivo no sistema de arquivos na linha de comando?

10

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

No Windows, eu executaria o seguinte:

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

Qual é o equivalente do Linux?

Iszi
fonte
Bem, obviamente há mais de uma maneira de esfolar esse gato. Ainda estou um pouco curioso para saber se há uma maneira de fazer isso ls?
Iszi

Respostas:

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

(Leia os principais termos e condições. Leia o manual para obter as letras miúdas.)

Listar o conteúdo de um diretório é uma espécie de recurso secundário ls. A principal tarefa de ls, que ocupa a maior parte de sua complexidade, é o ajuste fino da tela. (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 é verdade para o GNU ls que você ' você encontrará no Linux e em outros sistemas com menos opções desde os primeiros dias.)

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

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

A primeira ferramenta a executar a correspondência de padrões é o próprio shell. Você não precisa de nenhum outro comando: basta digitar seus curingas e 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*. A *corresponde a qualquer nome de arquivo ou qualquer parte do nome do arquivo, mas *.txtnão corresponde 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 no seu ~/.bashrc).

echo **/*filename*

O echocomando apenas ecoa a lista de nomes de arquivos gerados pela parte de trás do escudo em você. Como uma exceção, se não houver um nome de arquivo correspondente, o padrão curinga permanecerá inalterado no bash (a menos que você defina shopt -s nullglob; nesse caso, o padrão será expandido para uma lista vazia) e zsh sinalizará um erro (a menos que você defina setopt nullglobou setopt no_no_matchque faz com que o padrão permaneça inalterado).

Você ainda pode querer usar lspara suas opções. Por exemplo, lspode dar indicações sobre a natureza ou as permissões do arquivo (diretório, executável etc.) por meio de cores. Você pode exibir a data, tamanho e propriedade do arquivo 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 ficheiros cujo nome corresponde ao padrão *filename*no diretório atual e seus subdiretórios e imprimir 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, -printestá implícito. Além disso, se você não especificar nenhum diretório a percorrer ( /some/diracima), o diretório atual estará implícito. A condição -name '*filename'diz para listar (ou agir) apenas os arquivos cujo nome corresponde a esse padrão; existem muitos outros filtros, como -mtime -1os arquivos modificados nas últimas 24 horas. Às vezes, você pode omitir as aspas -name '*filename*', mas apenas se o 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 todas as noites. A vantagem do locateexcesso find /é que é muito mais rápido. Uma desvantagem é que suas informações podem ser obsoletas. Existem várias implementações locateque diferem em seu comportamento em sistemas multiusuário: o locateprograma básico indexa apenas arquivos legíveis publicamente (convém executar o companheiro updatedbpara criar um segundo banco de dados que indexe todos os arquivos da sua conta); existem outras versões (mlocate, slocate) que indexam todos os arquivos e fazem com que o locateprograma filtre o banco de dados para retornar apenas os arquivos que você pode ver.

locate filename

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

Gilles 'SO- parar de ser mau'
fonte
Gostaria de poder votar novamente novamente. Só tinha que procurar por outro projeto hoje à noite. Mais uma vez obrigado, @Gilles!
Iszi
6

o equivalente ao seu exemplo do DOS seria:

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

No Linux, você geralmente não precisa mais do -printargumento. Se você estiver trabalhando em outros sistemas operacionais, pode ser útil saber sobre isso.

Tim Kennedy
fonte
5

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

Na instalação padrão (no Ubuntu), locateconfigura um crontrabalho diário que verifica 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, geralmente é mais rápido do que findou lsapenas executar sudo updatedbe depois locate. É definitivamente mais rápido se você precisar fazer mais pesquisas ... como o próprio nome sugere, updatedbatualiza o banco de dados que locateutiliza ...

locatepossui regex interno, o que o torna muito útil ... Vou usar findem um script, mas raramente uso findna linha de comando. Eu até uso locateem scripts (pessoais) ... por exemplo.locate -bir "oo.*datt.*mp4$"

locate retorna os caminhos totalmente qualificados dos arquivos correspondentes.

Peter.O
fonte
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 findpara obter mais informações sobre o comando find e argumentos,

Josh-Caim
fonte
3
Você precisa citar ou escapar dos *s para impedir que o shell os interprete.
Shawn J. Goff
Essa distribuição / shell é específica? Eu o executei no Fedora 16 sem escapes e funcionou bem.
precisa
1
Existem opções em algumas conchas que transmitem as estrelas ao programa se elas não coincidirem com nada. Tente criar um arquivo no diretório atual que corresponda a esse padrão e tente o comando novamente.
Shawn J. Goff