Pytanie Wyklucz podkatalog przy użyciu find


Mam taką strukturę katalogów

data
|___
   |
   abc
    |____incoming
   def
    |____incoming
    |____processed
   123
    |___incoming
   456
    |___incoming
    |___processed

W każdym folderze w katalogu danych znajduje się folder podrzędny. Chcę uzyskać wszystkie pliki ze wszystkich folderów i podfolderów z wyjątkiem def / przychodzących i 456 / przychodzących katalogów. Próbowałem wykonać następujące polecenie

 find /home/feeds/data -type d \( -name 'def/incoming' -o -name '456/incoming' -o -name arkona \) -prune -o -name '*.*' -print

ale nie działa zgodnie z oczekiwaniami.

Ravi


76
2017-11-19 19:11


pochodzenie


To nie jest dobra rada, ale pozwoli ci wydostać się z wielu sytuacji szybko i brudno: rób to grep -v something wykluczyć to, czego nie chcesz - Miquel


Odpowiedzi:


To działa:

find /home/feeds/data -type f -not -path "*def/incoming*" -not -path "*456/incoming*"

Wyjaśnienie:

  • find /home/feeds/data: rozpocznij wyszukiwanie rekurencyjnie od określonej ścieżki
  • -type f: znajduj tylko pliki
  • -not -path "*def/incoming*": nie dołączaj do niczego def/incoming jako część swojej ścieżki
  • -not -path "*456/incoming*": nie dołączaj do niczego 456/incoming jako część swojej ścieżki

143
2017-11-19 19:22



błąd "znajdź: zła opcja - nie znajdź: lista predykatów listy ścieżek" - Ravi
@Ravi używasz powłoki bash? Właśnie przetestowałem to na moim terminalu i to działa dla mnie. Spróbuj skopiować i wkleić rozwiązanie, jeśli dokonałeś modyfikacji skryptu. - sampson-chen
Działa, ale wymienia pliki dirs nie w tych katalogach. - Ravi
@Ravi oh, przepraszam - myliłem to, czego szukałeś. Zmiana type d do -type f i znajdzie pliki zamiast katalogów (Zobacz zaktualizowaną odpowiedź) - sampson-chen
Wielkie dzieki. - Ravi


Tylko ze względu na dokumentację: Być może będziesz musiał kopać głębiej, ponieważ istnieje wiele konstelacji search'n'skip (tak jak musiałem). Może się to okazać prune jest twoim przyjacielem, podczas gdy -not -path nie zrobi tego, czego się spodziewasz.

Jest to więc cenny przykład 15 znalezionych przykładów, które wykluczają katalogi:

http://www.theunixschool.com/2012/07/find-command-15-examples-to-exclude.html 

Aby połączyć się z początkowym pytaniem, wykluczenie w końcu zadziałało jak dla mnie:

find . -regex-type posix-extended -regex ".*def/incoming.*|.*456/incoming.*" -prune -o -print 

Następnie, jeśli chcesz znaleźć jeden plik i nadal wykluczyć pathes, po prostu dodaj | grep myFile.txt.

Może to zależeć również od twojej wersji find. Widzę:

$ find -version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX

5
2017-08-04 07:15





-name tylko dopasowuje nazwę pliku, a nie całą ścieżkę. Chcesz użyć -path zamiast tego dla części, w których przycina się katalogi, takie jak def/incoming.


4
2017-11-19 19:16





find $(INP_PATH} -type f -ls |grep -v "${INP_PATH}/.*/"

1
2018-01-17 22:12



Niektóre wyjaśnienia mogą uczynić z tego znacznie lepszą odpowiedź. - Cris Luengo
Dziękujemy za ten fragment kodu, który może zapewnić krótkoterminową pomoc w ograniczonym zakresie. Właściwe wyjaśnienie znacznie poprawiłoby jego długoterminową wartość, pokazując, dlaczego jest to dobre rozwiązanie problemu i sprawiłoby, że będzie on bardziej przydatny dla przyszłych czytelników z innymi, podobnymi pytaniami. Zmodyfikuj odpowiedź, aby dodać wyjaśnienia, w tym założenia, które podjąłeś - Shawn C.