Come trovare un file nel filesystem dalla riga di comando?


10

Vorrei scoprire dove si trova un file (con un nome file parzialmente noto) nel file system. Mi piacerebbe sapere come farlo dalla riga di comando, piuttosto che utilizzare un'utilità GUI.

In Windows, esegui quanto segue:

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

Qual è l'equivalente di Linux?


Bene, c'è ovviamente più di un modo per scuoiare questo gatto. Sono ancora un po 'curioso di sapere se c'è un modo per farlo ls?
Iszi,

Risposte:


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

(Continua a leggere per i termini e le condizioni principali. Leggi il manuale per la stampa fine.)

Elencare il contenuto di una directory è una specie di caratteristica secondaria di ls. Il lavoro principale di ls, quello che occupa la maggior parte della sua complessità, è la messa a punto del display. (Guarda il manuale e confronta il numero di opzioni relative alla scelta dei file da visualizzare con il numero di opzioni che controllano quali informazioni visualizzare su ciascun file e come viene formattato il display. Questo è vero sia per GNU che per te ' lo troverai su Linux e su altri sistemi con meno opzioni, sin dai primi tempi.)

La modalità predefinita di lsè che quando gli passi una directory, elenca i file in quella directory. Se lo passi a qualsiasi altro tipo di file (file normale, collegamento simbolico, ecc.), Elenca solo quel file. (Questo vale separatamente per ogni argomento.) L'opzione -ddice di lsnon scendere mai in una directory.

lsha un'opzione -Rche gli dice di elencare ricorsivamente le directory. Ma ha un'applicabilità limitata e non consente molti filtri sull'output.

Il primo strumento per eseguire la corrispondenza dei modelli è la shell stessa. Non hai bisogno di nessun altro comando: basta digitare i caratteri jolly e il gioco è fatto. Questo è noto come globbing .

echo *filename*

Tradizionalmente, i caratteri jolly erano limitati alla directory corrente (o alla directory indicata:) echo /some/where/*filename*. A *corrisponde a qualsiasi nome file o parte del nome file, ma *.txtnon corrisponderà foo/bar.txt. Le shell moderne hanno aggiunto il modello **/che significa "in questa directory, o in qualsiasi directory sottostante (ricorsivamente)". Con bash, per motivi di compatibilità storica, questa funzione deve essere abilitata esplicitamente con shopt -s globstar(puoi inserire questa riga nel tuo ~/.bashrc).

echo **/*filename*

Il echocomando fa semplicemente eco all'elenco dei nomi dei file generati dalla shell. Come eccezione, se non esiste alcun nome file corrispondente, il modello jolly rimane invariato in bash (a meno che non sia impostato shopt -s nullglob, nel qual caso il modello si espande in un elenco vuoto) e zsh segnala un errore (a meno che non si imposti setopt nullglob, oppure setopt no_no_matchche fa in modo che il modello rimanga invariato).

Potresti comunque voler utilizzare lsper le sue opzioni. Ad esempio, lspuò fornire indicazioni sulla natura o le autorizzazioni del file (directory, eseguibile, ecc.) Tramite i colori. Potresti voler visualizzare la data, la dimensione e la proprietà del file con ls -l. Consulta il manuale per molte altre opzioni.

Il comando tradizionale per cercare un file in un albero di directory è find. Viene fornito con molte opzioni per controllare quali file visualizzare e cosa farne. Ad esempio, per cercare i file il cui nome corrisponde al modello *filename*nella directory corrente e nelle sue sottodirectory e stamparne i nomi:

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

-printè un'azione (la maggior parte delle altre azioni consiste nell'eseguire un comando sul file); se non metti un'azione, -printè implicito. Inoltre, se non si specifica alcuna directory da attraversare ( /some/dirsopra), viene implicita la directory corrente. La condizione -name '*filename'dice di elencare (o agire) solo i file il cui nome corrisponde a quel modello; ci sono molti altri filtri, ad esempio -mtime -1per abbinare i file modificati nelle ultime 24 ore. A volte puoi omettere le virgolette -name '*filename*', ma solo se il carattere jolly non corrisponde a nessun file nella directory corrente (vedi sopra). Tutto sommato, la forma abbreviata è

find -name '*filename*'

Un altro strumento utile quando si conosce (parte di) il nome di un file è locate. Questo strumento interroga un database di nomi di file. Sui sistemi tipici, viene aggiornato ogni notte. Il vantaggio di locateover find /è che è molto più veloce. Un aspetto negativo è che le sue informazioni potrebbero essere obsolete. Esistono diverse implementazioni locateche differiscono nel loro comportamento sui sistemi multiutente: il locateprogramma di base indicizza solo i file leggibili pubblicamente (potresti voler eseguire il compagno updatedbper creare un secondo database che indicizzi tutti i file nel tuo account); ci sono altre versioni (mlocate, slocate) che indicizzano tutti i file e hanno il locateprogramma che filtra il database per restituire solo i file che puoi vedere.

locate filename

A volte pensi che un file sia fornito da un pacchetto nella tua distribuzione, conosci (parte di) il nome del file ma non il nome del pacchetto e desideri installare il pacchetto. Molte distribuzioni forniscono uno strumento per questo. Su Ubuntu, lo è apt-file search filename. Per comandi equivalenti su altri sistemi, controllare Pacman Rosetta .


Vorrei poter votare nuovamente questo. Ho dovuto cercare questo per un altro progetto stasera. Grazie ancora, @Gilles!
Iszi,

6

l'equivalente del tuo esempio DOS sarebbe:

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

Su Linux generalmente non hai più bisogno -printdell'argomento, comunque. Se ti ritrovi a lavorare su altri sistemi operativi, può essere utile conoscerlo.


5

Se vuoi qualcosa di "veloce" , ma non in una situazione critica e vuoi solo sapere se esiste e dove si trova, puoi usarlo locate. Mantiene un database di tutti i file nelle directory in cui gli hai detto di raccogliere informazioni.

Nell'installazione predefinita (su Ubuntu), locateimposta un cronlavoro quotidiano che esegue la scansione del file system e aggiorna il database ...

Se ritieni di dover aggiornare il database prima del prossimo aggiornamento cron, in genere è più veloce di findo lssemplicemente eseguirlo sudo updatedbe quindi locate. È decisamente più veloce se devi fare più ricerche ... come suggerisce il nome, updatedbaggiorna il database che locateutilizza ...

locateha regex integrato, il che lo rende molto utile ... Lo userò findin uno script, ma lo uso raramente finddalla riga di comando. Uso persino locatenegli script (personali) ... ad es.locate -bir "oo.*datt.*mp4$"

locate restituisce i percorsi completi dei file corrispondenti.


2
find [path] -name [filename]

Ad esempio, se voglio cercare nella directory / home un nome file contenente pippo, vorrei usare il comando:

find /home -name *foo*

usa il comando man findper maggiori informazioni sul comando find e sugli argomenti,


3
È necessario citare o sfuggire a *s per impedire alla shell di interpretarli.
Shawn J. Goff,

Quella distro / shell è specifica? L'ho eseguito in Fedora 16 senza fughe e ha funzionato bene.
josh-cain,

1
Ci sono opzioni in alcune shell che trasmettono le stelle al programma se non corrispondono a nulla. Prova a creare un file nella directory corrente che corrisponde a quel modello e prova di nuovo il comando.
Shawn J. Goff,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.