Jak wykluczyć ten folder / bieżący / kropkowy ze znalezionego „typu d”

186
find . -type d

można użyć do znalezienia wszystkich katalogów poniżej jakiegoś punktu początkowego. Ale zwraca bieżący katalog ( .) zbyt, które mogą być niepożądane. Jak można to wykluczyć?

Matthias Ronge
źródło

Odpowiedzi:

194

Rozwiązanie POSIX 7 :

find . ! -path . -type d

W tym konkretnym przypadku ( .) golfy są lepsze niż mindepthrozwiązanie (24 vs 26 znaków), chociaż prawdopodobnie jest to nieco trudniejsze do wpisania z powodu !.

Aby wykluczyć inne katalogi, gra będzie słabsza i wymaga zmiennej SUSZENIA:

D="long_name"
find "$D" ! -path "$D" -type d

Moje drzewo decyzyjne pomiędzy !i -mindepth:

  • scenariusz? Użyj !dla przenośności.
  • sesja interaktywna na GNU?
    • wykluczyć .? Rzuć monetą.
    • wykluczyć long_name? Zastosowanie -mindepth.
Ciro Santilli
źródło
jeśli chcesz wykluczyć wiele ścieżek, po prostu zrób find /path/ ! -path "/path/first" ! -path "/path/second"to tylko w ten sposób?
Vincent De Smet
2
@VincentDeSmet, czy chcesz wykluczyć tylko te ścieżki, czy nie powrócić do nich? Jeśli tylko ścieżki, możesz użyć find / ! -regex '/\(a\|b\)/.*'lub prościej, przeciągnij przez grep. Aby się nie powtórzyć, powyższe byłoby bardzo nieefektywne i powinieneś użyć -prune: stackoverflow.com/questions/1489277/...
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
mój problem był następujący: chciałem rekurencyjnie usunąć wszystko w katalogu oprócz 1 podkatalogu. Użyłem findz, grepaby wykluczyć katalog, ale katalog macierzysty nadal tam był, powodując, że i tak wszystko zostało usunięte.
Vincent De Smet,
@VincentDeSmet Nie widzę bezpośredniego rozwiązania find, musisz sprawdzić prefiksy: stackoverflow.com/questions/17959317/… Ale Bash for loop może to obsłużyć :-)
Ciro Santilli 郝海东 冠状 病 六四 事件法轮功
Prawdopodobnie chcesz uciec od wykrzyknika char ( \!), aby być po bezpiecznej stronie. Wszystkie przykłady w mojej maszynie man finduciekły, więc wygląda na to, że to prawdopodobnie Good Idea ™. Edytuj - Właśnie zauważyłem, że nawet wyraźnie mówi:! expr True if expr is false. This character will also usually need protection from interpretation by the shell.
Adrian Günter
201

Parametr findmoże kontrolować nie tylko głębokość rekurencji -maxdepth, ale także ograniczać głębokość od „góry” za pomocą odpowiedniego -mindepthparametru. Więc tak naprawdę potrzebujemy:

find . -mindepth 1 -type d
Matthias Ronge
źródło
5
działa na znalezieniu GNU, ale niestety jest rozszerzeniem GNU do znalezienia POSIX 7 , a nawet LSB używa narzędzi powłoki POSIX (nie rozszerzonych GNU)
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
6
To zadziałało dla mnie. Mianowicie:find . -mindepth 1 -maxdepth 1 -type d ...
racl101,
19

Używam, find ./* <...>gdy nie mam nic przeciwko ignorowaniu plików dot. Pierwszego poziomu ( *glob nie domyślnie dopasowuje ich do bash - patrz opcja „dotglob” we wbudowanym shopt: https://www.gnu.org/software/bash /manual/html_node/The-Shopt-Builtin.html ).

eclipse tmp # find.
.
./ekran
./screen/.testfile2
./.X11-unix
./.ICE-unix
./tmux-0
./tmux-0/default
eclipse tmp # find ./*
./ekran
./screen/.testfile2
./tmux-0
./tmux-0/default
Milos Ivanovic
źródło
Do Twojej wiadomości nie używaj tej sztuczki z -execopcją. Na przykład, jeśli spróbujesz find dir/* -type d -exec rmdir {} \;, zobaczysz błędy.
plhn
Mylisz się, a może źle doradzasz. To polecenie będzie działać poprawnie. Jeśli widzisz błędy, będą pochodzić rmdiri najprawdopodobniej powiedzą ci, że katalogi nie są puste, ponieważ findnajpierw przeprowadzą głębokie przeszukanie katalogów, pokazując rodziców przed dziećmi.
Milos Ivanovic
2
Uwaga: „ignorowanie plików dot. Pierwszego poziomu” oznacza również wykluczenie wszystkich ukrytych plików / katalogów.
Jonathan H
2

Cóż, proste obejście również (rozwiązanie nie działało dla mnie w Windows Git Bash)

find * -type d

Może nie jest zbyt wydajny, ale wykonuje zadanie i czasem tego potrzebujemy.

[Edytuj]: Jak skomentował @AlexanderMills, nie pokaże ukrytych katalogów w lokalizacji głównej (np. ./.hidden), Ale pokaże ukryte podkatalogi (np. ./folder/.hiddenSub). [Testowane z git bash na Windowsie]

StackHola
źródło