2013-04-25 8 views
5

Załóżmy, że mam katalog zawierający pewną liczbę podkatalogów, z których każda zawiera pewną liczbę plików. Chcę sprawdzić, który z tych katalogów nie zawiera konkretnego pliku. Na przykład, jeśli są to moje katalogi:Wyklucza katalogi w find, które nie zawierają konkretnej nazwy pliku?

dir/A: 
    foo 
    bar 
dir/B: 
    bar 
dir/C: 
    foo 
dir/D: 
dir/E: 
    foo 
    bar 

Gdybym chciał wymienić wszystkie katalogi nie zawierające foo, chciałbym uzyskać:

dir/B 
dir/D 

Czy można to zrobić z unix find, czy Muszę użyć jakiegoś alternatywnego narzędzia?

Odpowiedz

7

znalazłem dobre rozwiązanie po trochę więcej badań:

find . -type d \! -exec test -e '{}/foo' \; -print

Gdzie zastępujesz foo dowolnym plikiem, którego szukasz.

Spowoduje to wydrukowanie listy wszystkich katalogów, które nie zawierają żadnych plików, których szukasz.

+0

Czy istnieje sposób usunięcia bieżącego folderu './', który jest obecny w danych wyjściowych ?, ponieważ gdybym musiał skopiować te podkatalogi do innego katalogu, obecność '. /' Byłaby szkodliwa – WanderingMind

0
comm -3 <(find -type d) <(find -name foo -printf '%h\n') 
  • dostać wszystkie katalogi
  • dostać tylko katalogi, które zawierają foo
  • porównanie, drukowanie tylko różnicę
0

1 - Tworzenie 1 skrypt po prostu liniowej w bieżącym katalogu (lub gdzieś na twojej ścieżce). Nazwijmy to check.sh:

cd "$1" && [[ ! -f "$2" ]] && pwd 

2 - Daj wykonać uprawnienie do powyższego skryptu:

chmod +x ./check.sh 

3 - Wreszcie użyć tego polecenia znajdują się:

find . -maxdepth 1 -type d -exec ./check.sh '{}' foo \; 
0

Trochę późno do partii, oto jedno-liner, że powinno działać:

ls | xargs -I dir ls dir/foo > /dev/null 

Sztuką jest to, że ls */foo dyskretnie przejść nad niedopasowanych katalogów (katalogi, które nie zawierają „foo”), więc użycie xargs zmusi go do dostarczenia nam danych wyjściowych do stderr w katalogach, które nie zawierają foo. W takim razie wystarczy wyrzucić stdout, aby zobaczyć, czego szukamy.

Powiązane problemy