Comment trouver un fichier dans le système de fichiers à partir de la ligne de commande?

10

Je voudrais savoir où se trouve un fichier (avec un nom de fichier partiellement connu) dans le système de fichiers. Je voudrais savoir comment faire cela à partir de la ligne de commande, plutôt que d'utiliser un utilitaire GUI.

Sous Windows, j'exécuterais ce qui suit:

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

Quel est l'équivalent Linux?

Iszi
la source
Eh bien, il y a bien évidemment plus d'une façon de dépouiller ce chat. Je suis toujours un peu curieux de savoir s'il y a moyen de le faire ls?
Iszi

Réponses:

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

(Lisez la suite pour les principales conditions générales. Lisez le manuel pour les petits caractères.)

Lister le contenu d'un répertoire est une sorte de fonctionnalité secondaire de ls. Le travail principal de ls, celui qui occupe la majeure partie de sa complexité, est de peaufiner son affichage. (Regardez le manuel et comparez le nombre d'options liées au choix des fichiers à afficher par rapport au nombre d'options qui contrôlent les informations à afficher sur chaque fichier et la façon dont l'affichage est formaté. Cela est vrai pour les deux GNU que vous '' Je vais trouver sur Linux, et sur d' autres systèmes avec moins d'options, depuis les premiers jours.)

Le mode par défaut lsest que lorsque vous lui passez un répertoire, il répertorie les fichiers dans ce répertoire. Si vous lui passez un autre type de fichier (fichier normal, lien symbolique, etc.), il répertorie uniquement ce fichier. (Cela s'applique à chaque argument séparément.) L'option -dindique de lsne jamais descendre dans un répertoire.

lsa une option -Rqui lui indique de lister les répertoires de manière récursive. Mais son applicabilité est limitée et ne permet pas beaucoup de filtrage sur la sortie.

Le tout premier outil pour effectuer la correspondance de motifs est le shell lui-même. Vous n'avez besoin d'aucune autre commande: tapez simplement vos caractères génériques et vous êtes prêt. Ceci est connu sous le nom de globbing .

echo *filename*

Traditionnellement, les caractères génériques étaient limités au répertoire actuel (ou au répertoire indiqué:) echo /some/where/*filename*. A *correspond à n'importe quel nom de fichier ou partie de nom de fichier, mais *.txtne correspondra pas foo/bar.txt. Les shells modernes ont ajouté le motif **/qui signifie «dans ce répertoire, ou dans n'importe quel répertoire en dessous (récursivement)». Avec bash, pour des raisons de compatibilité historique, cette fonctionnalité doit être explicitement activée avec shopt -s globstar(vous pouvez mettre cette ligne dans votre ~/.bashrc).

echo **/*filename*

La echocommande fait simplement écho à la liste des noms de fichiers générés par le shell. Par exception, s'il n'y a aucun nom de fichier correspondant, le modèle générique reste inchangé dans bash (sauf si vous le définissez shopt -s nullglob, auquel cas le modèle se développe dans une liste vide), et zsh signale une erreur (sauf si vous le définissez setopt nullglob, ou setopt no_no_matchce qui fait que le motif reste inchangé).

Vous pouvez toujours vouloir utiliser lsses options. Par exemple, lspeut donner des indications sur la nature ou les autorisations du fichier (répertoire, exécutable, etc.) à travers les couleurs. Vous souhaiterez peut-être afficher la date, la taille et la propriété du fichier avec ls -l. Consultez le manuel pour de nombreuses autres options.

La commande traditionnelle pour rechercher un fichier dans une arborescence de répertoires est find. Il est livré avec de nombreuses options pour contrôler les fichiers à afficher et ce que vous devez en faire. Par exemple, pour rechercher des fichiers dont le nom correspond au modèle *filename*dans le répertoire en cours et ses sous-répertoires et imprimer leurs noms:

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

-printest une action (la plupart des autres actions consistent à exécuter une commande sur le fichier); si vous ne mettez pas d'action, -printest implicite. De plus, si vous ne spécifiez aucun répertoire à parcourir ( /some/dirci-dessus), le répertoire actuel est implicite. La condition -name '*filename'indique de répertorier (ou d'agir) uniquement les fichiers dont le nom correspond à ce modèle; il existe de nombreux autres filtres, par exemple pour -mtime -1faire correspondre les fichiers modifiés au cours des dernières 24 heures. Vous pouvez parfois omettre les guillemets -name '*filename*', mais uniquement si le caractère générique ne correspond à aucun fichier du répertoire actuel (voir ci-dessus). Dans l'ensemble, la forme courte est

find -name '*filename*'

Un autre outil utile lorsque vous connaissez (une partie de) le nom d'un fichier est locate. Cet outil interroge une base de données de noms de fichiers. Sur les systèmes typiques, il est actualisé tous les soirs. L'avantage de locateOver find /est qu'il est beaucoup plus rapide. Un inconvénient est que ses informations peuvent être périmées. Il existe plusieurs implémentations locatedont le comportement diffère sur les systèmes multi-utilisateurs: le locateprogramme de base indexe uniquement les fichiers lisibles par le public (vous souhaiterez peut-être exécuter le compagnon updatedbpour créer une deuxième base de données qui indexe tous les fichiers de votre compte); il existe d'autres versions (mlocate, slocate) qui indexent tous les fichiers et font locatefiltrer la base de données par le programme pour ne renvoyer que les fichiers que vous pouvez voir.

locate filename

Parfois, vous pensez qu'un fichier est fourni par un package dans votre distribution, vous connaissez (en partie) le nom du fichier mais pas le nom de votre package, et vous souhaitez installer le package. De nombreuses distributions fournissent un outil pour cela. Sur Ubuntu, ça l'est apt-file search filename. Pour des commandes équivalentes sur d'autres systèmes, consultez le Pacman Rosetta .

Gilles 'SO- arrête d'être méchant'
la source
J'aimerais pouvoir voter à nouveau. Il fallait juste chercher ça pour un autre projet ce soir. Merci encore, @Gilles!
Iszi
6

l'équivalent de votre exemple DOS serait:

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

Sous Linux, vous n'avez généralement plus besoin de l' -printargument, cependant. Si vous travaillez sur d'autres systèmes d'exploitation, il peut être utile de le savoir.

Tim Kennedy
la source
5

Si vous voulez quelque chose de "rapide" , mais pas dans une situation critique et que vous voulez seulement savoir s'il existe et où il se trouve, vous pouvez l'utiliser locate. Il conserve une base de données de tous les fichiers dans les répertoires sur lesquels vous lui avez demandé de collecter des informations.

Dans l'installation par défaut (sur Ubuntu), locateconfigure un crontravail quotidien qui analyse le système de fichiers et met à jour la base de données ...

Si vous sentez que vous devez mettre à jour la base de données avant la prochaine mise à jour cron, elle est généralement plus rapide que findou lsà exécuter sudo updatedb, puis locate. C'est certainement plus rapide si vous avez besoin de faire plus de recherches ... comme son nom l'indique, updatedbmet à jour la base de données qui locateutilise ...

locatea regex intégré, ce qui le rend très pratique ... Je vais utiliser finddans un script, mais j'utilise rarement finden ligne de commande. J'utilise même locatedans des scripts (personnels) ... par exemple.locate -bir "oo.*datt.*mp4$"

locate renvoie les chemins d'accès complets des fichiers correspondants.

Peter.O
la source
2
find [path] -name [filename]

Par exemple, si je veux rechercher dans le répertoire / home un nom de fichier contenant foo, j'utiliserais la commande:

find /home -name *foo*

utilisez la commande man findpour plus d'informations sur la commande find et les arguments,

josh-cain
la source
3
Vous devez citer ou échapper les *s pour empêcher le shell de les interpréter.
Shawn J. Goff
Cette distribution / shell est-elle spécifique? Je l'ai exécuté dans Fedora 16 sans échapper et cela a bien fonctionné.
josh-cain
1
Il existe des options dans certains obus qui transmettent les étoiles au programme si elles ne correspondent à rien. Essayez de créer un fichier dans votre répertoire actuel qui correspond à ce modèle et essayez à nouveau la commande.
Shawn J. Goff,