Come mostrare solo i file nascosti in Terminal?


154

Ho una directory che contiene migliaia di file, alcuni dei quali sono nascosti.

Il comando ls -aelenca tutti i file, compresi quelli nascosti, ma ho solo bisogno di elencare i file nascosti.

Quale comando dovrei usare?


1
Un semplice ls -ld .*o ls -ald .*funzionerà
John Strood

Risposte:


189

Il comando :

ls -ld .?* 

Elencherà solo i file nascosti.

Spiega:

 -l     use a long listing format

 -d, --directory
              list  directory entries instead of contents, and do not derefer‐
              ence symbolic links

.?* will only state hidden files 

8
Non sono necessari i due punti interrogativi, il * lo copre (? Corrisponde solo a un singolo carattere, * corrisponde a qualsiasi numero di essi).
psusi

13
@psusi, penso che l'intenzione sia quella di escludere .e ..dalla partita. Tuttavia escluderà anche i nomi di file nascosti a carattere singolo (perfettamente legali) come .a, .1e così via. Forse un globo più esteso sarebbe .!(|.)cioè punto letterale seguito da qualsiasi cosa tranne niente o un altro (singolo) punto cioèls -d .!(|.)
steeldriver

@steeldriver, pulito, il ?? la versione esclude "." e "..". Questo sembra essere il risultato di una stranezza interessante: nessuno dei due? né * corrisponderà a un punto, ma il? deve corrispondere a qualcosa altrimenti il ​​nome viene ignorato.
psusi

Per identificare directory e file aggiungere l'opzione F, ovvero i nomi di directory ls -ldF.? * Hanno "/" come i file dei caratteri visualizzati per ultimi.
RCF

1
Questo funziona quasi tranne che elenca anche le cartelle nascoste come .vim, che non considero un file qui. Lo modifico un po 'come ls -ldp.? * | grep -v / Questo solo elenco di file nascosti non cartella nascosta
Fred Yang,

31
ls -d .!(|.)

Fa esattamente quello che OP sta cercando.


1
Come funziona?
SarcasticSully

elenca qualsiasi cosa con a. e non elencare nulla senza uno è ciò in cui si traduce praticamente.
patrick,

1
Capisco che in !(pattern-list), pattern-listè un elenco di uno o più schemi separati da un |, ma è confuso per me che non hai alcun modello a sinistra di |. Potresti spiegarmi questa sintassi, per favore?
Carlos Mendoza,

2
@CarlosMendoza che sarebbe diventato il modello vuoto, quindi questo è come .non seguito da (niente o .), escludendo .se stesso e ...
muru,

16

Se vuoi solo i file nella tua directory corrente (nessuna ricorsione), puoi farlo

echo .[^.]*

Ciò stamperà i nomi di tutti i file il cui nome inizia con una .ed è seguito da uno o più caratteri non punti. Nota che ciò non funzionerà per i file il cui nome inizia con punti consecutivi, quindi ad esempio ....foonon verrà mostrato.

Puoi anche usare find:

find -mindepth 1 -prune -name '.*'

Le -mindepthassicura che non corrispondono .ed i -prunemezzi che findnon scende in sottodirectory.



4

Utilizzando finde awk,

find . -type f | awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

Spiegazione:

find . -type f -> Elenca tutti i file nella directory corrente insieme al suo percorso come,

./foo.html
./bar.html
./.foo1

awk -F"/" '$NF ~ /^\..*$/ {print $NF}'

/come separatore di campo awk controlla l'ultimo campo che fissa con un punto o no. Se inizia con un punto, stampa l'ultimo campo della riga corrispondente.


Potresti semplicemente usare find -type f. Non è necessario impostare esplicitamente il percorso di ricerca o -name "*".
terdon

3

find di solito è un'opzione migliore per ricerche complicate rispetto all'uso del nome globbing.

find . -mindepth 1 -maxdepth 1 -name '.*'

o

find . -mindepth 1 -maxdepth 1 -name '.*' -o -name '*~'

find . cerca la directory corrente

-mindepth 1esclude. e .. dalla lista

-maxdepth 1 limita la ricerca alla directory corrente

-name '.*' trova i nomi dei file che iniziano con un punto

-o o

-name '*~' trova nomi di file che terminano con una tilde (in genere si tratta di file di backup da programmi di modifica del testo)

Tuttavia, questa e tutte le altre risposte mancano i file che si trovano nel .hiddenfile della directory corrente . Se stai scrivendo uno script, queste righe leggeranno il .hiddenfile e visualizzeranno i nomi dei file di quelli esistenti.

if [[ -f .hidden]] # if '.hidden' exists and is a file
then
    while read filename # read file name from line
    do
        if [[ -e "$filename" ]] # if the read file name exists
        then
            echo "$filename" # print it
        fi
    done < .hidden # read from .hidden file
fi

Qual è il .hiddenfile? Perché dovrebbe mai esserci un file chiamato .hiddenche contiene i nomi dei file? Ad ogni modo, se ce n'è uno, perché dovresti fare qualcosa di così complesso quando tutto ciò di cui hai bisogno sarebbe cat .hidden? Il tuo findcomando è corretto (ish) ma -name '*~'è irrilevante. I file che finiscono in tilde sono file di backup ma non nascosti in alcun modo.
terdon

@terdon Il .hiddenfile è per file e cartelle che si desidera nascondere quando non è possibile modificare il nome del file / cartella per iniziare con un punto. Per quanto riguarda i file che finiscono in tilde, dipende dal sistema. ls -Bignorerà tali file, così come la maggior parte dei file explorer della GUI.
Mark H,

cat .hiddenpotrebbe mostrare file che non esistono più se tali file sono stati eliminati o spostati da quando sono stati aggiunti al .hiddenfile.
Mark H,

Funziona bene
Penghe Geng,

2

Penso che puoi farlo con il seguente comando.

ls -a | grep "^\." | grep -v "^\.$" | grep -v "^\..$"

ls -a comando inserito, che mostra tutti i file e le directory nella directory di lavoro corrente.

grep "^\."comando che ho aggiunto, che filtra l'output per mostrare solo i file nascosti (il suo nome inizia con ".").

grep -v "^\.$" | grep -v "^\..$" comando che ho aggiunto, che filtra l'output per escludere., .. (Sono directory corrente e parent).

Se alcuni nomi di file possono avere più di una riga con "\n", l'esempio sopra potrebbe essere errato.

Quindi suggerisco il seguente comando per risolverlo.

find -maxdepth 1 -name ".[!.]*"


@ RaduRădeanu Ho visto il tuo commento, è così bello. Ho modificato di nuovo la mia risposta. Grazie per il tuo commento
xiaodongjie,

2

Cos'altro avresti potuto fare, is ls .?*o ls .!(|)che ti mostrerà tutto nella directory corrente, file nascosti / directory in alto e altri file / directory in basso

ad es .: dal mio terminale

$ ls .?*       
.bash_history    .dmrc        .macromedia   .weather
.bash_logout     .gksu.lock   .profile      .wgetrc
.bash_profile    .bashrc.save .ICEauthority .toprc           .Xauthority
.bashrc          .lastdir     .viminfo      .xsession-errors
.bashrc~         .dircolors   .lynxrc       .vimrc           .xsession-errors.old

..:
Baron

.adobe:
Flash_Player

.aptitude:
cache  config

.cache:
compizconfig-1                              rhythmbox
dconf                                       shotwell

Ora noti i risultati sopra, ti mostra tutti i file / dir con il suo sottodir ed eventuali file nascosti proprio sotto.

[1:0:248][ebaron@37signals:pts/4][~/Desktop]
$ ls .!(|)
.bash_aliases  .bashrc1  .bashrc1~

..:
askapache-bash-profile.txt  examples.desktop             Public           top-1m.csv
backups             Firefox_wallpaper.png        PycharmProjects          top-1m.csv.zip
Desktop             java_error_in_PYCHARM_17581.log  Shotwell Import Log.txt  topsites.txt
Documents           Music                Templates            Videos
Downloads           Pictures                 texput.log           vmware

Spiacente, non posso commentare. di spiegare la differenza tra il qui ls .?*e @ risposta cioby23 ls -d .[!.]* .??*e perché è in realtà la stampa di file nascosti per due volte è perché letteralmente si sta chiedendo due volte .??*, .?*, .[!.]*sono la stessa cosa, quindi l'aggiunta di uno di essi, con diversi caratteri di comando verrà stampata due volte.


1

Puoi anche usare:

ls -d .[!.]* .??*

Ciò ti consentirà di visualizzare normali file nascosti e file nascosti che iniziano con 2 o 3 punti, ad esempio: ..hidden_file


1
Con questo ottengo tutti i file nascosti due volte.
TuKsn,

1

puoi usare il comando

ls -Ad .??*

Ciò ha il vantaggio di consentire un elenco a più colonne, a differenza dell'approccio basato su grep nelle ls -a | grep "^\."soluzioni


1

Tutte le risposte finora si basano sul fatto che i file (o directory) i cui nomi iniziano con un punto sono "nascosti". Ho trovato un'altra soluzione, che potrebbe non essere altrettanto efficiente, ma questa soluzione non assume nulla riguardo ai nomi dei file nascosti e quindi evita di elencare ..il risultato (così come la risposta attualmente accettata).

Il comando completo è:

ls -d $(echo -e "$(\ls)\n$(\ls -A)" | sort | uniq -u)

Spiegazione

Ciò che fa è elencare tutti i file (e le directory) due volte,

echo -e "$(\ls)\n$(\ls -A)"

ma mostra solo una volta i file nascosti -A.

Quindi viene ordinato l'elenco | sortche fa apparire i file regolari (non nascosti) due volte e uno accanto all'altro.

Quindi, rimuovi tutte le linee che appaiono più di una volta | uniq -u, lasciando solo linee uniche.

Infine, utilizza lsnuovamente per elencare tutti i file con le opzioni personalizzate dell'utente e senza elencare il contenuto delle directory nell'elenco -d.

EDIT (Limitazioni):

Come ha sottolineato Muru, questa soluzione non funzionerà correttamente se ci sono file con nomi come escaped\ncharacter.txtperché echo -edivideranno il nome del file in due righe. Inoltre non funzionerà come previsto se ci sono due file nascosti con quasi lo stesso nome, tranne per un carattere speciale, come .foo[tab].txte .foo[new-line].txtpoiché entrambi vengono stampati come .foo?.txte sarebbero eliminati dauniq -u


1
Penso che sia praticamente la definizione di file nascosti. Anche l'origine di questi file nascosti deriva da un bug nel trattare .come primo personaggio.
muru,

Lo dico (come fatto) nel primo paragrafo. Tuttavia ottiene ancora un risultato diverso rispetto all'attuale risposta accettata
alejandro,

Certo, esclude .., ma mi chiedo quanto funzioni bene con nomi di file contenenti caratteri speciali.
muru,

Non so esattamente cosa intendi con caratteri speciali, ma penso che non costituirebbe un problema, poiché questa soluzione non assume nulla sui nomi dei file
alejandro,

In realtà, supponi almeno una cosa: i nomi dei file non hanno nuove righe. Inoltre: i nomi dei file non contengono sequenze di escape che echo -epossano interpretare. Inoltre: lsnon manipolerà i nomi dei file in modo che due nomi di file diversi vengano visualizzati allo stesso modo (ad esempio, in alcune versioni lsverranno utilizzati ?per caratteri speciali, quindi .foo\tbar( \t=> tab) e .foo\nbar( \n=> newline) appariranno entrambi come foo?bar).
muru,

1

In alternativa, puoi anche usare echo .*

per esempio

user@linux:~$ echo .*
. .. .bash_aliases .bash_history .bash_logout .bashrc
user@linux:~$

Se lo preferisci in un lungo elenco, converti semplicemente lo spazio bianco in una nuova riga.

user@linux:~$ echo .* | tr ' ' '\n'
.
..
.bash_aliases
.bash_history
.bash_logout
.bashrc
user@linux:~$ 

0

Con bash, l'impostazione della GLOBIGNOREvariabile speciale è un valore non vuoto è sufficiente per farlo ignorare .e ..quando si espandono globs. Dai documenti di Bash :

La GLOBIGNOREvariabile shell può essere utilizzata per limitare l'insieme di nomi di file che corrispondono a un modello. Se GLOBIGNOREimpostato, ogni nome file corrispondente che corrisponde anche a uno dei motivi in GLOBIGNOREviene rimosso dall'elenco delle corrispondenze. Se l' nocaseglobopzione è impostata, la corrispondenza con i motivi in GLOBIGNOREviene eseguita indipendentemente dal caso. I nomi dei file .e ..vengono sempre ignorati quando GLOBIGNOREè impostato e non null. Tuttavia, l'impostazione GLOBIGNOREsu un valore non nullo ha l'effetto di abilitare l'opzione shell dotglob, quindi tutti gli altri nomi di file che iniziano con un ‘.'corrisponderanno.

Se lo impostiamo su .:.., entrambi .e ..verranno ignorati. Dato che impostandolo su qualcosa di diverso da null otterrà anche questo comportamento, potremmo anche impostarlo su just.

Così:

GLOBIGNORE=.
ls -d .*
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.