Jak wyświetlić tylko pliki, a nie katalogi Bash?


87

Jak wyświetlić listę wszystkich plików w jednym folderze, ale bez ich folderów lub plików podrzędnych. Innymi słowy: jak mogę wyświetlić tylko pliki?




Żaden z proponowanych duplikatów nie wydaje się realizować wymogu pomijania katalogów.
tripleee

Odpowiedzi:


118

Używając find:

find . -maxdepth 1 -type f

Użycie tej -maxdepth 1opcji zapewnia, że ​​będziesz szukać tylko w bieżącym katalogu (lub, jeśli zastąpisz .jakąś ścieżką, tym katalogu). Jeśli chcesz uzyskać pełną rekurencyjną listę wszystkich plików w tym i podkatalogach, po prostu usuń tę opcję.


Po moim komentarzu do odpowiedzi mklement0 zdałem sobie sprawę, że "find ./*.png -maxdepth 1 -type f> pngs.txt" prawdopodobnie dałoby to samo. To robi. Bez instalowania skryptu.
Alex Hall

2
findna mac, nie ma ani -type, ani -maxdepthopcji.
Timofey,

1
@Tim: -typei -maxdepthnie są opcjami w normalnym sensie; BSD find(używane na OS X) nazywa je prawyborach , i muszą one pochodzić po nazwie pliku operandów (S) ( .w tym przypadku; uwaga, że w przeciwieństwie na Linux, BSD potrzeby wersji przynajmniej jeden wyraźny filename operand); polecenie w tej odpowiedzi zdecydowanie działa na komputerze Mac.
mklement0

1
@AlexHall: To sprytne rozwiązanie (chociaż sugeruję find *.png -maxdepth 0 -type funikanie ./przedrostka w nazwach plików wyjściowych; zwróć także uwagę na -maxdepthof 0, nie 1), o ile potrzebujesz tylko nazw plików w kolejności alfabetycznej . Jeśli chcesz, co lsmożna zrobić dla Ciebie w inny sposób (inny format wyjściowy / kolejność, bezpośrednia kontrola nad tym, czy ukryte elementy są uwzględnione, czy nie), uzupełnione o filtrowanie [wielu] typów, skrypt z mojej odpowiedzi może pomóc.
mklement0

1
Dla kontrastu find * -maxdepth 0 -type f(alternatywa wywodząca się z komentarza @ AlexHall) z find . -maxdepth 1 -type fodpowiedzią: find . ...niezmiennie zawiera ukryte elementy, niezmiennie przedrostki plików wyjściowych z ./, aw przypadku GNU find(Linux) zazwyczaj wyświetla nieposortowaną listę. find * ...ze względu na zezwolenie powłoce na wykonanie globalizacji z góry, domyślnie wyklucza ukryte elementy (można to zmienić shopt -s dotglob), wyświetla same nazwy plików (bez prefiksu), posortowane alfabetycznie. Żadne podejście nie obejmuje dowiązań symbolicznych do plików; użyj opcji, -Laby to zrobić.
mklement0

15
ls -p | grep -v /

ls -p pozwala pokazać / po nazwie folderu, która działa jak znacznik do usunięcia.


Miło jest zobaczyć przykład wykorzystujący lsoprócz find, ponieważ ten ostatni zwraca ścieżki względne, a poprzednie tylko nazwy plików. Użyj odpowiedniego narzędzia do pracy.
Ben Amos

5
  • Oparta na Carlpetcie findodpowiedź ( find . -maxdepth 1 -type f) działa w zasadzie, ale nie jest tym samym, co użycie ls: otrzymujesz potencjalnie nieposortowaną listę nazw plików z prefiksami./ i tracisz możliwość zastosowania lswielu opcji ;
    również find niezmiennie znajduje ukryte elementy , podczas gdy ls„zachowanie zależy od obecności lub braku opcji -alub -A.

    • Poprawa , sugerowane przez Alex Hall w komentarzu na pytanie jest łączenie powłoki masek zfind :

          find * -maxdepth 0 -type f  # find -L * ... includes symlinks to files
      
      • Jednakże, chociaż rozwiązuje to problem z prefiksami i daje wyniki posortowane alfabetycznie , nadal nie masz (w linii) kontroli nad włączaniem ukrytych elementów ani dostępu do lswielu innych opcji sortowania / formatu wyjściowego.
  • Odpowiedź ls+grep Hansa Roggemana jest pragmatyczna, ale ogranicza cię do używania -lformatu wyjściowego long ( ) .


Aby rozwiązać te ograniczenia, napisałem narzędzie fls( f iltering ls ) ,

  • narzędzie, które zapewnia elastyczność wyjściową,ls a jednocześnie zapewnia możliwość filtrowania typu ,
  • po prostu umieszczając znaki filtrujące typy, takie jak fpliki, dkatalogi i ldowiązania symboliczne przed listą lsargumentów (uruchom fls --helplub fls --mandowiedz się więcej).

Przykłady:

fls f        # list all files in current dir.
fls d -tA ~  #  list dirs. in home dir., including hidden ones, most recent first
fls f^l /usr/local/bin/c* # List matches that are files, but not (^) symlinks (l)

Instalacja

Obsługiwane platformy

  • W przypadku instalacji z rejestru npm : Linux i macOS
  • W przypadku instalacji ręcznej : każda platforma typu Unix z Bash

Z rejestru npm

Uwaga: Nawet jeśli nie używasz Node.js, jego menedżer pakietów npmdziała na różnych platformach i jest łatwy w instalacji; próbować
curl -L https://git.io/n-install | bash

Po zainstalowaniu Node.js zainstaluj w następujący sposób:

[sudo] npm install fls -g

Uwaga :

  • To, czy potrzebujesz, sudozależy od tego, jak zainstalowałeś Node.js / io.js i czy później zmieniłeś uprawnienia ; jeśli pojawi się EACCESbłąd, spróbuj ponownie z sudo.

  • -gZapewnia globalną instalację i jest potrzebne, aby umieścić flsw systemowym $PATH.

Instalacja ręczna

  • Pobierz ten bashskrypt jako fls.
  • Spraw, aby był wykonywalny za pomocą chmod +x fls.
  • Przenieś lub dowiązanie symboliczne do folderu w Twoim $PATH, na przykład /usr/local/bin(macOS) lub /usr/bin(Linux).

1
Znakomity. Nawet jeśli wymaga to stworzenia kolejnego skryptu. Skopiowałem i wkleiłem ze źródła w postaci zwykłego tekstu do pliku tekstowego i uruchomiłem go w Cygwin za pomocą tego polecenia: fls.sh f * .png> pngs.txt I bingo: lista plików .png bez ścieżek. Ale naprawdę, ls nie ma opcji porównywalnej z przełącznikiem "dir / b" w systemie DOS? Przejrzałem zawartość wyjścia ls --help i przynajmniej nic takiego tam nie ma.
Alex Hall

1
@AlexHall: Dzięki; tl; dr: try -1(numer jeden); lsw rzeczywistości domyślnie jest to „gołe” wyjście, tj. tylko nazwy plików, ale podczas wysyłania do terminala używa układu opartego na kolumnach (wiele nazw plików w linii). Aby uzyskać jedną nazwę pliku na linię wyjściową (co dir /brobi, jeśli pamięć jest obsługiwana), użyj -1opcji, która jest w rzeczywistości włączona, gdy standardowe wyjście nie jest podłączone do terminala, na przykład podczas wysyłania do potoku lub pliku wyjściowego.
mklement0

2

Wyświetlanie zawartości jakiegoś katalogu, bez podkatalogów

Lubię korzystać z lsopcji, na przykład:

  • -l użyj formatu długich list
  • -t sortuj według czasu modyfikacji, najpierw najnowsze
  • -r odwrotna kolejność podczas sortowania
  • -F, --classify dołącz wskaźnik (jeden z * / => @ |) do wpisów
  • -h, --human-readable z -l i -s, rozmiary wydruku, takie jak 1K 234M 2G itp ...

Czasami --colori wszyscy inni. (Zobacz ls --help)

Wymieniam wszystko oprócz folderów

Spowoduje to wyświetlenie plików, dowiązań symbolicznych, urządzeń, potoków, gniazd itp.

więc

find /some/path -maxdepth 1 ! -type d

można łatwo posortować według daty:

find /some/path -maxdepth 1 ! -type d -exec ls -hltrF {} +

Tylko lista plików :

lub

find /some/path -maxdepth 1 -type f

posortowane według rozmiaru:

find /some/path -maxdepth 1 -type f -exec ls -lSF --color {} +

Zapobiegaj wyświetlaniu ukrytych wpisów :

Aby nie pokazywać ukrytych wpisów, których nazwa zaczyna się kropką, możesz dodać ! -name '.*':

find /some/path -maxdepth 1 ! -type d ! -name '.*' -exec ls -hltrF {} +

Następnie

Można zastąpić /some/pathprzez .do listy do bieżącego katalogu lub ..do katalogu nadrzędnego .


1

Możesz również użyć lsz greplub egrepi umieścić go w swoim profilu jako alias:

ls -l | egrep -v '^d'
ls -l | grep -v '^d'

Nie umieściłbym tego w skrypcie z podanego powyżej powodu, ale inne szybkie i brudne rozwiązanie: ls -F | grep -v '/ $'
mooie

1

znajdź pliki: ls -l / home | grep "^ -" | tr -s '' | wytnij -d '' -f 9

znajdź katalogi: ls -l / home | grep "^ d" | tr -s '' | wytnij -d '' -f 9

znajdź linki: ls -l / home | grep "^ l" | tr -s '' | wytnij -d '' -f 9

tr -s '' zamienia dane wyjściowe w plik rozdzielany spacjami, a polecenie cut mówi, że separatorem jest spacja, i zwraca 9. pole (zawsze nazwa pliku / nazwa katalogu / nazwa dowiązania).

Używam tego cały czas!


Łał! Co jeśli nazwy plików zawierają spacje?
F. Hauri

użyj „9-”, aby uzyskać wszystko od 9 pola dalej. Dotyczy to również linków, ponieważ będą znajdować się po dziewiątym polu.
Richard

0
{ find . -maxdepth 1 -type f | xargs ls -1t | less; }

dodane, xargsaby działało, i używane -1zamiast -lpokazywać tylko nazwy plików bez dodatkowych lsinformacji


Ma to pewną zaletę, ponieważ wymusza sortowanie według czasu, chociaż są prawdopodobnie mniej niezgrabne sposoby, aby to zrobićfind -printf0 '...' | sort -z
tripleee

-2

Dodam tylko do odpowiedzi Carletta. Aby uzyskać bardzo użyteczny widok plików, możesz przesłać dane wyjściowe do ls.

find . -maxdepth 1 -type f|ls -lt|less

Pokazuje ostatnio zmodyfikowane pliki w formacie listy, co jest bardzo przydatne, gdy pobrałeś dużo plików i chcesz zobaczyć niezakłóconą wersję ostatnich.


3
To prawdopodobnie nie działa tak, jak się spodziewasz! lsnie czyta standardowego wejścia, więc potokowanie czegokolwiek do potoku jest bezcelowe ls. Tęskniłeś xargs?
gniourf_gniourf

Ujmując to inaczej: findpolecenie w tej odpowiedzi jest całkowicie ignorowane ; ogólne polecenie jest takie samo jak ls -lt | less, które nie przeprowadza filtrowania typów.
mklement0

1
Chociaż z GNU findmożesz to zrobić find . -maxdepth 1 -type f -ls. Wydaje się również do pracy na Mac OS, chociaż wierzę, -maxdepthi -lsnie są właściwie opcje przenośne.
tripleee

-2

"find '-maxdepth'" nie działa z moją starą wersją basha, dlatego używam:

dla f w $ (ls); zrób, jeśli [-f $ f]; następnie echo $ f; fi; Gotowe


Użycie for f in $(ls)jest podwójnie błędne. Możesz to naprawić, for f in *ale wtedy by się zepsuł, ponieważ nie cytujesz argumentu echopoprawnie.
tripleee
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.