Come posso generare un elenco di file con il loro percorso assoluto in Linux?


304

Sto scrivendo uno script di shell che accetta percorsi di file come input.

Per questo motivo, devo generare elenchi di file ricorsivi con percorsi completi. Ad esempio, il file barha il percorso:

/home/ken/foo/bar

ma, per quanto posso vedere, entrambi lse finddanno solo elenchi di percorsi relativi:

./foo/bar   (from the folder ken)

Sembra un requisito ovvio, ma non riesco a vedere nulla nelle pagine man findo ls.

Come posso generare un elenco di file nella shell compresi i loro percorsi assoluti?


uso:find /home/ken/foo/bar -exec ls -ld $PWD/{} \;
Studente il

Risposte:


305

Se dai findun percorso assoluto per cominciare, stamperà percorsi assoluti. Ad esempio, per trovare tutti i file .htaccess nella directory corrente:

find "$(pwd)" -name .htaccess

o se la shell si espande $PWDnella directory corrente:

find "$PWD" -name .htaccess

find semplicemente antepone il percorso che è stato dato a un percorso relativo al file da quel percorso.

Greg Hewgill ha anche suggerito di utilizzare pwd -Pse si desidera risolvere i collegamenti simbolici nella directory corrente.


9
Se si desidera risolvere anche i collegamenti simbolici, utilizzare pwd -P.
Greg Hewgill,

5
Questo è utile, ma penso che la risposta di user431529 di seguito sia più valida: ls -d -1 $PWD/**/*ma credo che funzioni find $PWDanche (testato in bash)
Brian

9
@Brian Why? find $PWDè semplice. L' lsincantesimo è complesso e ingombrante (a meno che tu non lo alias). findnon dipende dalle espansioni della shell glob, quindi funzionerà in qualsiasi shell. findè anche molto più flessibile, posso ottenere un elenco ricorsivo di tutti i file, o forse di tutte le directory, o forse voglio un elenco di tutti i file xml o tutti i file modificati nell'ultima settimana. Tutto ciò è possibile con find, ma non facilmente con ls.
Matthew Scharley,

12
Ho dovuto usare a find "`pwd`" -name .htaccesscausa degli spazi nei nomi delle directory
Paulo Casaretto

Non capisco, questo comando non mi dà il percorso assoluto del file I, mentre altre risposte in fondo alla lista fanno il lavoro.
Bjørn Otto Vasbotten,

202
readlink -f filename 

dà il percorso assoluto completo. ma se il file è un collegamento simbolico, otterrai il nome risolto finale.


8
Bello. Non funziona sulla variante BSD di readlink (cioè Mac). Uso gnucoreutils su mac. E quindi può usare greadlink che funziona con la soluzione sopra.
Sheki,

12
Non andare su Mac OS X.
Andrew Lazarus,

1
@AndrewLazarus - Per Mac OS X, utilizzare realpathinvece
cz

se installi gli strumenti bash tramite brew install coreutils, il file eseguibile verrà installato come/usr/local/opt/coreutils/libexec/gnubin/readlink
redolent il

121

Usa questo per dirs (il /dopo **è necessario in bash per limitarlo alle directory):

ls -d -1 "$PWD/"**/

questo per file e directory direttamente nella directory corrente, i cui nomi contengono un .:

ls -d -1 "$PWD/"*.*

questo per tutto:

ls -d -1 "$PWD/"**/*

Tratto da qui http://www.zsh.org/mla/users/2002/msg00033.html

In bash, **è ricorsivo se si abilita shopt -s globstar.


1
ls -d -1 $ PWD / ** / * non ricorre. Vorrei poter riprendere il mio +1. Puoi fare ** per ogni profondità che devi percorrere.
user606723,

4
L'operatore ** è un operatore di globbing ricorsivo. Se si utilizza il comando in una shell che lo supporta (come zsh), funzionerà correttamente.
zebediah49,

ls -d1 "$ PWD /"{*,.*} per catturare anche i file nascosti (punto). Per me la versione ricorsiva nella risposta non ha anteposto il percorso assoluto ai file nelle sottocartelle.
Zael,

Penso che dovrò usare find ... I get -> bash: / bin / ls: lista degli argomenti troppo lunga
TelamonAegisthus

30

Puoi usare

find $PWD 

in bash


3
Ciò fornirà il percorso della directory corrente e anche tutti i file e le directory sottostanti. Probabilmente non è quello che la gente sta cercando.
Bill

18
ls -d "$PWD/"*

Questo sembra solo nella directory corrente . Cita "$ PWD" nel caso contenga spazi.


Questa è ancora una risposta molto valida, ma sarebbe bene includere le informazioni che non funzionano in modo ricorsivo (che è quello che stavo effettivamente cercando!)
bbbco

1
Per uso ricorsivo: trova. -exec ls -ld $ PWD / {} \;
Studente il

10

Comando: ls -1 -d "$PWD/"*

Questo fornirà i percorsi assoluti del file come di seguito.

[root@kubenode1 ssl]# ls -1 -d "$PWD/"*
/etc/kubernetes/folder/file-test-config.txt
/etc/kubernetes/folder/file-test.txt
/etc/kubernetes/folder/file-client.txt

8

Il $PWDè una buona opzione da Matthew sopra. Se vuoi trovare solo la stampa di file, puoi anche aggiungere l'opzione -ty f per cercare solo i file normali. Altre opzioni sono "d" solo per le directory, ecc. Quindi nel tuo caso lo sarebbe (se voglio cercare solo i file con .c ext):

find $PWD -type f -name "*.c" 

o se vuoi tutti i file:

find $PWD -type f

Nota: non è possibile creare un alias per il comando precedente, poiché $ PWD viene completato automaticamente nella directory principale quando l'alias viene impostato da bash.


In realtà, -d non significa solo directory, ma tratta le directory come file. Quindi se ls -d / home, tornerai "/ home", non un elenco di ciò che è in / home.
Travis

@Travis: stava parlando dell'opzione da trovare, non di ls. Nel suo caso "find / -type d" troverà solo le directory - come ha detto.
oligofren,

6

Se si assegna al comando find un percorso assoluto, sputerà i risultati con un percorso assoluto. Quindi, dalla directory Ken se dovessi digitare:

find /home/ken/foo/ -name bar -print    

(invece del relativo percorso find . -name bar -print)

Dovresti ricevere:

/home/ken/foo/bar

Pertanto, se vuoi un ls -le farlo restituire il percorso assoluto, puoi semplicemente dire al comando find di eseguire un ls -lsu qualunque cosa trovi.

find /home/ken/foo -name bar -exec ls -l {} ;\ 

NOTA: c'è uno spazio tra {}e;

Otterrai qualcosa del genere:

-rw-r--r--   1 ken admin       181 Jan 27 15:49 /home/ken/foo/bar

Se non sei sicuro di dove sia il file, puoi sempre cambiare il percorso di ricerca. Finché il percorso di ricerca inizia con "/", in cambio otterrai un percorso assoluto. Se stai cercando una posizione (come /) in cui otterrai molti errori di autorizzazione negata, ti consiglio di reindirizzare l'errore standard in modo da poter effettivamente vedere i risultati della ricerca:

find / -name bar -exec ls -l {} ;\ 2> /dev/null

( 2>è la sintassi per le shell Borne e Bash, ma non funzionerà con la shell C. Potrebbe funzionare anche con altre shell, ma so solo che funziona in Bourne e Bash).


Puoi passare più arg allo stesso lsprocesso con -exec ls -ld {} +. (Probabilmente non si desidera -davere il lscontenuto della directory dell'elenco). O meglio, usa find's built-in lscon find ... name bar -ls. Inoltre, hai la sintassi sbagliata per un arg per comando: devi citare il punto e virgola dalla shell, quindi è così {} \;.
Peter Cordes,

5

fd

Utilizzando fd(in alternativa a find), utilizzare la sintassi seguente:

fd . foo -a

Dov'è .il modello di ricerca ed fooè la directory principale.

Ad esempio, per elencare tutti i file in etcmodo ricorsivo, run: fd . /etc -a.

-a, --absolute-path Mostra percorsi assoluti anziché relativi


2

Solo un'alternativa a

ls -d "$PWD/"* 

per individuare l' *espansione della shell, quindi

echo "$PWD/"*

farebbe lo stesso (l'inconveniente che non puoi usare -1per separare da nuove linee, non spazi).


puoi approfondire di più su questo? cos'è un'espansione della shell? come usare -1per separare per linee?
Antonio Araujo,

@Antonio Araujo, l'espansione della shell è la shell (ad esempio bash) sostituirà * con un elenco di file - può leggere di più sulla pagina man di bash. -1 è l'opzione di comando ls, echo è un altro comando, non ha le stesse opzioni.
Marisha,

1
lspwd() { for i in $@; do ls -d -1 $PWD/$i; done }

1

Ecco un esempio che stampa un elenco senza un periodo aggiuntivo e che dimostra anche come cercare una corrispondenza di file. Spero che questo ti aiuti:

find . -type f -name "extr*" -exec echo `pwd`/{} \; | sed "s|\./||"

1

Questo ha funzionato per me. Ma non è elencato in ordine alfabetico.

find "$(pwd)" -maxdepth 1

Questo comando elenca alfabeticamente e elenca anche i file nascosti.

ls -d -1 "$PWD/".*; ls -d -1 "$PWD/"*;

1

stat

Percorso assoluto di un singolo file:

stat -c %n "$PWD"/foo/bar

1

Potresti provare questo.

for name in /home/ken/foo/bar/*
do
    echo $name
done

Puoi ottenere il percorso degli addominali usando forloop e echosemplicemente senza find.


0

Se hai bisogno di un elenco di tutti i file nelle directory attuali e secondarie

find $PWD -type f

Se hai bisogno di un elenco di tutti i file solo nella directory corrente

find $PWD -maxdepth 1 -type f

0

Questo darà il percorso canonico (risolverà i collegamenti simbolici): realpath FILENAME

Se si desidera il percorso canonico del collegamento simbolico stesso, quindi: realpath -s FILENAME


0

La maggior parte se non tutti i metodi suggeriti danno come risultato percorsi che non possono essere utilizzati direttamente in altri comandi del terminale se il percorso contiene spazi. Idealmente i risultati avranno anteprime. Questo funziona per me su macOS:

find / -iname "*SEARCH TERM spaces are okay*" -print 2>&1  | grep -v denied |grep -v permitted |sed -E 's/\ /\\ /g'

-1

find / -print farà questo


1
... sfortunatamente farà qualcos'altro (come visualizzare "alcuni" altri file a meno che non vengano filtrati)
DerMike

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.