Jak wyświetlić tylko ukryte pliki w terminalu?

154

Mam katalog zawierający tysiące plików, niektóre z nich są ukryte.

Polecenie wyświetla ls -alistę wszystkich plików, w tym ukrytych, ale muszę tylko wyświetlić ukryte pliki.

Jakiego polecenia powinienem użyć?

nux
źródło
1
Prosty ls -ld .*lub ls -ald .*zadziała
John Strood

Odpowiedzi:

189

Komenda :

ls -ld .?* 

Wyświetla tylko ukryte pliki.

Wyjaśnić :

 -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
źródło
8
Nie potrzebujesz tam dwóch znaków zapytania, * pokrywa je (? Pasuje tylko do jednego znaku, * pasuje do dowolnej ich liczby).
psusi
13
@psusi, myślę, że intencją jest, aby wykluczyć .i ..od meczu. Jednak będzie to również wykluczyć (doskonale prawnych) Single-znakowe nazwy plików, takich jak ukryte .a, .1i tak dalej. Być może lepszym rozszerzonym globem byłaby .!(|.)np. Dosłowna kropka, po której następuje cokolwiek oprócz nic lub innej (pojedynczej) kropki, tj.ls -d .!(|.)
steeldriver
@steeldriver, schludny, ?? wersja wyklucza „.” i "..". To wydaje się być wynikiem ciekawego dziwactwa: ani jednego? ani * dopasuje kropkę, ale? musi pasować do czegoś, w przeciwnym razie nazwa zostanie zignorowana.
psusi
Aby zidentyfikować katalogi i pliki, dodaj opcję F., tzn. Nazwy katalogów ls -ldF.? * Mają znaki „/”, tak jak ostatnio wyświetlane pliki znaków.
RCF
1
To prawie działa, z wyjątkiem tego, że wyświetla także ukryty folder, taki jak .vim, którego uważam tutaj za plik. Zmieniam to trochę jak ls -ldp.? * | grep -v / Ta lista zawiera tylko ukryte pliki, a nie ukryty folder
Fred Yang
31
ls -d .!(|.)

Robi dokładnie to, czego szuka OP.

Patrick
źródło
1
Jak to działa?
SarcasticSully
wylistuj katalog cokolwiek z. i nie wymieniaj niczego bez jednego, na co to właściwie tłumaczy.
Patrick
1
Rozumiem, że w !(pattern-list), pattern-listto lista jednego lub więcej wzorców rozdzielonych |, ale to jest mylące dla mnie, że nie ma żadnego wzoru po lewej stronie |. Czy możesz mi wyjaśnić tę składnię?
Carlos Mendoza
2
@CarlosMendoza, który stałby się pustym wzorem, więc nie jest .to po nim (nic lub .), wyłączając .siebie i ...
muru
16

Jeśli chcesz tylko pliki w bieżącym katalogu (bez rekurencji), możesz to zrobić

echo .[^.]*

Spowoduje to wydrukowanie nazw wszystkich plików, których nazwa zaczyna się na .a, po których następuje jeden lub więcej znaków niepunktowych. Pamiętaj, że to się nie powiedzie w przypadku plików, których nazwa zaczyna się od kolejnych kropek, więc na przykład ....foonie będzie wyświetlana.

Możesz także użyć find:

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

Te -mindepth, zapewnia, że nie pasują .i -pruneoznacza, że findnie będzie zejść do podkatalogów.

terdon
źródło
15
ls -ad .*

pracuje dla mnie w Bash.

znak
źródło
Pokazy .i ..Bash
Penghe Geng
4

Używanie findi awk,

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

Wyjaśnienie:

find . -type f -> Wyświetl wszystkie pliki w bieżącym katalogu wraz z jego ścieżką, np.

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

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

/jako awk separatora pól sprawdza, czy ostatnie pole patrzy kropką, czy nie. Jeśli zaczyna się od kropki, drukuje ostatnie pole odpowiadającej linii.

Avinash Raj
źródło
Możesz po prostu użyć find -type f. Nie musisz jawnie ustawiać ścieżki wyszukiwania lub -name "*".
terdon
3

find jest zwykle lepszą opcją dla skomplikowanych wyszukiwań niż stosowanie globowania nazw.

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

lub

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

find . przeszukuje bieżący katalog

-mindepth 1wyklucza i .. z listy

-maxdepth 1 ogranicza wyszukiwanie do bieżącego katalogu

-name '.*' znajdź nazwy plików zaczynające się od kropki

-o lub

-name '*~' znajdź nazwy plików, które kończą się tyldy (zazwyczaj są to pliki kopii zapasowych z programów do edycji tekstu)

Jednak w tej i wszystkich innych odpowiedziach brakuje plików znajdujących się w .hiddenpliku bieżącego katalogu . Jeśli piszesz skrypt, linie te odczytują .hiddenplik i wyświetlają nazwy plików, które istnieją.

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.
źródło
Jaki jest .hiddenplik Dlaczego miałby istnieć plik o nazwie .hiddenzawierającej nazwy plików? W każdym razie, jeśli istnieje jedno, dlaczego miałbyś zrobić coś tak złożonego, gdy wszystko, czego potrzebujesz, byłoby cat .hidden? Twoje findpolecenie jest poprawne (ish), ale nie -name '*~'ma znaczenia. Pliki kończące się tyldami są plikami kopii zapasowych, ale nie są w żaden sposób ukryte.
terdon
@terdon .hiddenPlik dotyczy plików i folderów, które chcesz ukryć, gdy nie możesz zmienić nazwy pliku / folderu, tak aby zaczynał się kropką. Jeśli chodzi o pliki kończące się tyldami, zależy to od systemu. ls -Bzignoruje takie pliki, podobnie jak większość eksploratorów plików GUI.
Mark H
cat .hiddenmoże pokazywać pliki, które już nie istnieją, jeśli pliki te zostały usunięte lub przeniesione od czasu dodania do .hiddenpliku.
Mark H
To działa dobrze.
Penghe Geng
2

Myślę, że możesz to zrobić za pomocą następującego polecenia.

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

ls -a wprowadzone polecenie, które pokazuje wszystkie pliki i katalogi w bieżącym katalogu roboczym.

grep "^\."Dołączyłem polecenie, które filtruje dane wyjściowe, aby wyświetlać tylko ukryte pliki (jego nazwa zaczyna się od ".").

grep -v "^\.$" | grep -v "^\..$" Dołączyłem polecenie, które filtruje dane wyjściowe, aby wykluczyć., .. (Są to katalog bieżący i nadrzędny).

Jeśli niektóre nazwy plików mogą zawierać więcej niż linię "\n", powyższy przykład może być niepoprawny.

Proponuję więc następujące polecenie, aby rozwiązać problem.

find -maxdepth 1 -name ".[!.]*"
xiaodongjie
źródło
6
Nigdy niels powinieneś analizować wyniku .
Radu Rădeanu
@ RaduRădeanu Widziałem twój komentarz, to takie dobre. Ponownie zredagowałem swoją odpowiedź. Dziękuję za komentarz.
xiaodongjie
2

Co jeszcze mogłeś zrobić, is ls .?*Lub ls .!(|)pokaże ci wszystko w bieżącym katalogu ukryte pliki / katalogi na górze i inne pliki / katalogi poniżej

np .: z mojego terminala

$ 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

Zauważ teraz w powyższych wynikach, że pokazuje on każdy plik / katalog wraz z jego podkatalogiem oraz wszelkie ukryte pliki poniżej.

[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

Przepraszam, nie mogę komentować. wyjaśnić różnicę pomiędzy tu ls .?*i @ cioby23 odpowiedź ls -d .[!.]* .??*i dlaczego jest to rzeczywiście drukowania plików ukrytych dwa razy, ponieważ jest dosłownie dwa razy pytasz .??*, .?*, .[!.]*oni to samo, więc dodanie każdy z nich z różnych znaków dowodzenia będzie drukować dwukrotnie.

amrx
źródło
1

Możesz także użyć:

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

Umożliwi to wyświetlanie normalnych ukrytych plików i ukrytych plików, które zaczynają się od 2 lub 3 kropek, na przykład: ..hidden_file

cioby23
źródło
1
Dzięki temu otrzymuję wszystkie ukryte pliki dwa razy.
TuKsn
1

możesz użyć polecenia

ls -Ad .??*

Ma to tę zaletę, że pozwala na wyświetlanie wielu kolumn, w przeciwieństwie do podejścia opartego na grep w ls -a | grep "^\."rozwiązaniach

Maythux
źródło
1

Wszystkie dotychczasowe odpowiedzi oparte są na tym, że pliki (lub katalogi), których nazwy zaczynają się od kropki, są „ukryte”. Wymyśliłem inne rozwiązanie, które może nie być tak wydajne, ale to rozwiązanie nie zakłada nic o nazwach ukrytych plików, a zatem unika wyświetlania ..w wyniku (podobnie jak obecnie akceptowana odpowiedź).

Pełne polecenie to:

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

Wyjaśnienie

Powoduje to wyświetlenie listy wszystkich plików (i katalogów) dwukrotnie,

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

ale tylko raz pokazuje ukryte pliki -A.

Następnie lista jest sortowana, | sortco powoduje, że zwykłe (nie ukryte) pliki pojawiają się dwa razy obok siebie.

Następnie usuń wszystkie linie, które pojawiają się więcej niż jeden raz | uniq -u, pozostawiając tylko unikalne linie.

Na koniec użyj lsponownie, aby wyświetlić listę wszystkich plików z niestandardowymi opcjami użytkownika i bez wyświetlania zawartości katalogów na liście -d.

EDYCJA (ograniczenia):

Jak zauważył muru, to rozwiązanie nie będzie działać poprawnie, jeśli istnieją pliki o nazwach takich jak np. escaped\ncharacter.txtPonieważ echo -epodzieli nazwę pliku na dwie linie. Nie będzie również działać zgodnie z oczekiwaniami, jeśli istnieją dwa ukryte pliki o prawie takiej samej nazwie, z wyjątkiem znaków specjalnych, takich jak .foo[tab].txti .foo[new-line].txtponieważ oba są drukowane jako .foo?.txti zostałyby wyeliminowane przezuniq -u

alejandro
źródło
1
Myślę, że taka jest definicja ukrytych plików. Nawet pochodzenie tych ukrytych plików wynika z błędu w postępowaniu z .pierwszą postacią.
muru
Wspominam o tym (jako fakt) w pierwszym akapicie. Nadal jednak otrzymuje inny wynik niż obecnie akceptowana odpowiedź
alejandro,
Jasne, to wyklucza .., ale zastanawiam się, jak dobrze działa z nazwami plików zawierającymi znaki specjalne.
muru
Nie wiem dokładnie, co masz na myśli przez znaki specjalne, ale sądzę, że nie stanowiłoby to problemu, ponieważ to rozwiązanie nie zakłada nic o nazwach plików
alejandro
W rzeczywistości zakładasz co najmniej jedno: w nazwach plików nie ma nowych linii. Ponadto: nazwy plików nie zawierają sekwencji specjalnych, które echo -ebędą interpretować. Ponadto: lsnie będzie zmieniać nazw plików, aby dwa różne nazwy plików były wyświetlane tak samo (na przykład w niektórych wersjach lsbędą używane ?znaki specjalne, więc oba .foo\tbar( \t=> tab) i .foo\nbar( \n=> nowa linia) będą wyświetlane jako foo?bar).
mur
1

Możesz także użyć echo .*

na przykład

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

Jeśli wolisz format długiej listy, po prostu zamień białe znaki na nową linię.

user@linux:~$ echo .* | tr ' ' '\n'
.
..
.bash_aliases
.bash_history
.bash_logout
.bashrc
user@linux:~$ 
Sabrina
źródło
0

W przypadku bash ustawienie GLOBIGNOREspecjalnej zmiennej jest pewne, że niepuste wartości wystarczą, aby ją zignorować .i ..podczas rozwijania globów. Z dokumentów Bash :

GLOBIGNOREZmiennej powłoki mogą być wykorzystywane do ograniczania zestaw nazwami dopasowania wzorca. Jeśli GLOBIGNOREjest ustawiony, każda pasująca nazwa pliku, która pasuje również do jednego z wzorców, GLOBIGNOREjest usuwana z listy dopasowań. Jeśli nocaseglobopcja jest ustawiona, dopasowanie do wzorców w GLOBIGNOREwykonywane jest bez względu na wielkość liter. Nazwy plików .i ..są zawsze ignorowane, gdy GLOBIGNOREsą ustawione, a nie null. Jednak ustawienie GLOBIGNOREwartości innej niż null powoduje włączenie opcji powłoki dotglob, więc wszystkie inne nazwy plików zaczynające się od ‘.„będą pasować”.

Jeśli ustawimy go .:.., zarówno .i ..zostaną zignorowane. Ponieważ ustawienie na cokolwiek innego niż null również spowoduje takie zachowanie, równie dobrze możemy ustawić to na just.

Więc:

GLOBIGNORE=.
ls -d .*
muru
źródło