Wie kann ich in Terminal nur versteckte Dateien anzeigen?

154

Ich habe ein Verzeichnis, das Tausende von Dateien enthält, von denen einige versteckt sind.

Der Befehl ls -alistet alle Dateien auf, auch versteckte, aber ich muss nur versteckte Dateien auflisten.

Welchen Befehl soll ich verwenden?

nux
quelle
1
Ein einfaches ls -ld .*oder ls -ald .*wird funktionieren
John Strood

Antworten:

189

Der Befehl :

ls -ld .?* 

Listet nur versteckte Dateien auf.

Erklären Sie:

 -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 
nux
quelle
8
Sie brauchen die beiden Fragezeichen dort nicht, das * deckt es ab (? Stimmt nur mit einem einzelnen Zeichen überein, * stimmt mit einer beliebigen Anzahl davon überein).
Psusi
13
@psusi, ich denke, die Absicht ist, .und ..aus dem Spiel auszuschließen . Allerdings wird es auch mit einem Zeichen versteckte Dateinamen wie auszuschließen ist (völlig legal) .a, .1und so weiter. Vielleicht wäre eine bessere erweiterten glob sein .!(|.)dh wörtliche Punkt durch nichts außer nichts oder ein anderes (single) gefolgt dh dotls -d .!(|.)
steeldriver
@steeldriver, ordentlich, die ?? Version schließt "." und "..". Dies scheint das Ergebnis einer interessanten Eigenart zu sein: Weder noch? noch * wird mit einem Punkt übereinstimmen, aber das? muss mit etwas übereinstimmen , sonst wird der Name ignoriert.
Psusi
Um Verzeichnisse und Dateien zu identifizieren, fügen Sie die Option F hinzu, dh ls -ldF.? * Verzeichnisnamen haben "/", während zuletzt angezeigte Zeichendateien dies nicht tun.
RCF
1
Dies funktioniert fast, außer es listet auch versteckte Ordner wie .vim auf, die ich hier nicht als Datei betrachte. Ich ändere es ein bisschen wie ls -ldp.? * | grep -v / Diese Liste nur versteckte Dateien nicht versteckten Ordner
Fred Yang
31
ls -d .!(|.)

Tut genau das, wonach OP sucht.

Patrick
quelle
1
Wie funktioniert das?
SarcasticSully
liste verzeichnis irgendetwas mit a. und nichts auflisten ohne eins ist, was es so ziemlich übersetzt.
Patrick
1
Ich verstehe, dass in !(pattern-list), pattern-listeine Liste von einem oder mehreren Mustern ist, die durch ein getrennt sind |, aber es ist für mich verwirrend, dass Sie links von kein Muster haben |. Könnten Sie mir bitte diese Syntax erklären?
Carlos Mendoza
2
@CarlosMendoza, das würde das leere Muster werden, so ist dies wie .nicht gefolgt von (nichts oder .), ohne sich .selbst und ...
muru
16

Wenn Sie nur die Dateien in Ihrem aktuellen Verzeichnis haben möchten (keine Rekursion), können Sie dies tun

echo .[^.]*

Dadurch werden die Namen aller Dateien gedruckt, deren Name mit einem beginnt .und auf die ein oder mehrere Nicht-Punkt-Zeichen folgen. Beachten Sie, dass dies für Dateien fehlschlägt, deren Name mit aufeinanderfolgenden Punkten beginnt und daher beispielsweise ....foonicht angezeigt wird.

Sie könnten auch verwenden find:

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

Das -mindepthstellt sicher, dass wir nicht übereinstimmen, .und das -prunebedeutet, dass findkeine Unterverzeichnisse erstellt werden.

terdon
quelle
15
ls -ad .*

arbeitet für mich in Bash.

Kennzeichen
quelle
Shows .und ..in Bash
Penghe Geng
4

Verwenden von findund awk,

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

Erläuterung:

find . -type f -> Listen Sie alle Dateien im aktuellen Verzeichnis zusammen mit dem Pfad wie folgt auf:

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

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

/Als Feldtrenner sucht awk nach dem letzten Feld, das mit einem Punkt markiert ist oder nicht. Beginnt es mit einem Punkt, wird das letzte Feld der entsprechenden Zeile gedruckt.

Avinash Raj
quelle
Du könntest es einfach benutzen find -type f. Sie müssen den Suchpfad oder nicht explizit festlegen -name "*".
terdon
3

find ist in der Regel eine bessere Option für komplizierte Suchvorgänge als die Verwendung von Namensglobbing.

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

oder

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

find . Durchsucht das aktuelle Verzeichnis

-mindepth 1schließt aus. und .. aus der Liste

-maxdepth 1 begrenzt die Suche auf das aktuelle Verzeichnis

-name '.*' Suchen Sie nach Dateinamen, die mit einem Punkt beginnen

-o oder

-name '*~' nach Dateinamen suchen, die mit einer Tilde enden (normalerweise sind dies Sicherungsdateien von Textbearbeitungsprogrammen)

In dieser und allen anderen Antworten fehlen jedoch Dateien, die sich in der .hiddenDatei des aktuellen Verzeichnisses befinden . Wenn Sie ein Skript schreiben, lesen diese Zeilen die .hiddenDatei und zeigen die Dateinamen der vorhandenen an.

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
Mark H
quelle
Was ist die .hiddenDatei? Warum sollte es jemals eine Datei geben .hidden, die die Dateinamen enthält? Wie auch immer, wenn es einen gibt, warum würden Sie dann etwas so Komplexes tun, wenn alles, was Sie brauchen würden, wäre cat .hidden? Ihr findBefehl ist korrekt (ish), aber das -name '*~'ist irrelevant. Dateien, die auf tildes enden, sind Sicherungsdateien, die jedoch in keiner Weise verborgen sind.
terdon
@terdon Die .hiddenDatei ist für Dateien und Ordner vorgesehen, die ausgeblendet werden sollen , wenn Sie den Datei- / Ordnernamen nicht so ändern können, dass er mit einem Punkt beginnt. Was Dateien betrifft, die auf Tilden enden, hängt dies vom System ab. ls -Bignoriert solche Dateien ebenso wie die meisten GUI-Datei-Explorer.
Mark H
cat .hiddenzeigt möglicherweise Dateien an, die nicht mehr vorhanden sind, wenn diese Dateien seit dem Hinzufügen zur .hiddenDatei gelöscht oder verschoben wurden .
Mark H
Das funktioniert gut.
Penghe Geng
2

Ich denke, dass Sie es mit folgendem Befehl tun können.

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

ls -a Der von Ihnen eingegebene Befehl zeigt alle Dateien und Verzeichnisse im aktuellen Arbeitsverzeichnis an.

grep "^\."Befehl, den ich angehängt habe, der die Ausgabe filtert, um nur versteckte Dateien anzuzeigen (der Name beginnt mit ".").

grep -v "^\.$" | grep -v "^\..$" Befehl, den ich angehängt habe, der die Ausgabe filtert, um auszuschließen., .. (Sie sind aktuell und übergeordnetes Verzeichnis).

Wenn einige Dateinamen mehr als eine Zeile mit haben können "\n", könnte das obige Beispiel falsch sein.

Deshalb schlage ich vor, dem Befehl zu folgen, um das Problem zu lösen.

find -maxdepth 1 -name ".[!.]*"
Xiaodongjie
quelle
6
Sie sollten niemals die Ausgabe von analysierenls .
Radu Rădeanu
@ RaduRădeanu Ich habe deinen Kommentar gesehen, es ist so gut. Ich habe meine Antwort erneut bearbeitet. Vielen Dank für Ihren Kommentar.
Xiaodongjie
2

Was Sie sonst noch hätten tun können, is ls .?*oder ls .!(|)das zeigt Ihnen alles in dem aktuellen Verzeichnis versteckte Dateien / Verzeichnisse oben und andere Dateien / Verzeichnisse unten

zB: von meinem Terminal

$ 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

Beachten Sie nun, dass in den obigen Ergebnissen alle Dateien / Verzeichnisse mit ihrem Unterverzeichnis und alle versteckten Dateien direkt darunter angezeigt werden.

[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

Entschuldigung, ich kann keinen Kommentar abgeben. den Unterschied hier zwischen zu erklären ls .?*und @ cioby23 Antwort ls -d .[!.]* .??*und warum es eigentlich versteckte Dateien zweimal Druck ist , weil buchstäblich zweimal Sie fragen .??*, .?*, .[!.]*sind sie die gleiche Sache, so dass jeder von ihnen mit verschiedenen Befehlszeichen Hinzufügen zweimal gedruckt wird.

amrx
quelle
1

Sie können auch verwenden:

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

Auf diese Weise können Sie normale versteckte Dateien und versteckte Dateien anzeigen, die mit zwei oder drei Punkten beginnen, zum Beispiel: ..hidden_file

cioby23
quelle
1
Damit bekomme ich alle versteckten Dateien zweimal.
TuKsn
1

Sie können den Befehl verwenden

ls -Ad .??*

Dies hat den Vorteil, dass im Gegensatz zum grep-basierten Ansatz in den ls -a | grep "^\."Lösungen eine mehrspaltige Auflistung möglich ist

Maythux
quelle
1

Alle bisherigen Antworten basieren auf der Tatsache, dass Dateien (oder Verzeichnisse), deren Namen mit einem Punkt beginnen, "versteckt" sind. Ich habe eine andere Lösung gefunden, die möglicherweise nicht so effizient ist, bei der jedoch keine Angaben zu den Namen der versteckten Dateien gemacht werden. Daher wird eine Auflistung ..im Ergebnis vermieden (ebenso wie die derzeit akzeptierte Antwort).

Der vollständige Befehl lautet:

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

Erläuterung

Auf diese Weise werden alle Dateien (und Verzeichnisse) zweimal aufgelistet.

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

Es werden jedoch nur einmal versteckte Dateien angezeigt -A.

Anschließend wird die Liste sortiert | sort, wodurch reguläre (nicht ausgeblendete) Dateien zweimal und nebeneinander angezeigt werden.

Entfernen Sie dann alle Zeilen, die mehrmals vorkommen | uniq -u, und lassen Sie nur einzelne Zeilen übrig.

Verwenden Sie schließlich lserneut, um alle Dateien mit den benutzerdefinierten Optionen des Benutzers aufzulisten, ohne den Inhalt der Verzeichnisse in der Liste aufzulisten -d.

EDIT (Einschränkungen):

Wie muru betonte, wird diese Lösung nicht richtig funktionieren, wenn es Dateien mit Namen gibt, zum Beispiel escaped\ncharacter.txtweil echo -eder Dateiname in zwei Zeilen aufgeteilt wird. Es wird auch nicht wie erwartet funktionieren, wenn es zwei versteckte Dateien mit fast dem gleichen Namen mit Ausnahme eines Sonderzeichen, wie .foo[tab].txtund .foo[new-line].txtwie diese beiden sind gedruckt , wie .foo?.txtund würden durch beseitigt werdenuniq -u

Alejandro
quelle
1
Ich denke, das ist so ziemlich die Definition von versteckten Dateien. Sogar der Ursprung dieser versteckten Dateien ist ein Fehler im Umgang mit .dem ersten Zeichen.
Muru
Ich erwähne das (als Tatsache) im ersten Absatz. Es wird jedoch immer noch ein anderes Ergebnis
angezeigt
Sicher, es schließt aus .., aber ich frage mich, wie gut es mit Dateinamen funktioniert, die Sonderzeichen enthalten.
Muru
Ich weiß nicht genau, was Sie mit Sonderzeichen meinen, aber ich würde denken, dass es kein Problem darstellen würde, da diese Lösung nichts über die Dateinamen
annimmt
Eigentlich nehmen Sie mindestens eines an: Dateinamen enthalten keine Zeilenumbrüche. Außerdem: Dateinamen enthalten keine Escape-Sequenzen, echo -edie interpretiert werden. Außerdem: lsVerfälscht Dateinamen nicht, sodass zwei unterschiedliche Dateinamen gleich angezeigt werden (in einigen Versionen lswerden sie beispielsweise ?für Sonderzeichen verwendet, sodass .foo\tbar( \t=> Tab) und .foo\nbar( \n=> Newline) beide als angezeigt werden foo?bar).
muru
1

Alternativ können Sie auch verwenden echo .*

z.B

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

Wenn Sie es in einem langen Listenformat bevorzugen, konvertieren Sie einfach den Leerraum in eine neue Zeile.

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

Mit bash GLOBIGNOREgenügt es, die Spezialvariable auf einen nicht leeren Wert zu setzen, damit sie ignoriert .und ..beim Erweitern von Globs. Aus den Bash-Dokumenten :

Die GLOBIGNOREShell-Variable kann verwendet werden, um die Anzahl der Dateinamen zu beschränken, die einem Muster entsprechen. Wenn festgelegt GLOBIGNOREist, wird jeder übereinstimmende Dateiname, der auch einem der Muster in entspricht GLOBIGNORE, aus der Liste der Übereinstimmungen entfernt. Wenn die nocaseglobOption aktiviert ist, wird der Abgleich mit den Mustern GLOBIGNOREunabhängig von der Groß- / Kleinschreibung durchgeführt. Die Dateinamen .und ..werden immer ignoriert, wenn GLOBIGNOREfestgelegt und nicht null. GLOBIGNOREWenn Sie jedoch einen Wert ungleich Null festlegen, wird die Option dotglob shell aktiviert, sodass alle anderen Dateinamen, die mit einem ‘.'beginnen, übereinstimmen.

Wenn wir es auf setzen .:.., werden beide .und ..ignoriert. Da das Setzen auf einen Wert ungleich Null auch dieses Verhalten hervorruft, können wir es genauso gut auf den Wert just setzen.

Damit:

GLOBIGNORE=.
ls -d .*
muru
quelle