Chcę znaleźć podkatalog bieżącego katalogu, który (tj. Podkatalog) zawiera 2 lub więcej zwykłych plików.
Nie interesują mnie katalogi zawierające mniej niż 2 pliki, ani katalogi zawierające tylko podkatalogi.
Oto zupełnie inne podejście oparte na GNU find
i uniq
. Jest to o wiele szybsze i bardziej przyjazne dla procesora niż odpowiedzi oparte na wykonywaniu polecenia powłoki, które zlicza pliki dla każdego znalezionego katalogu.
find . -type f -printf '%h\n' | sort | uniq -d
find
Komenda drukuje katalog wszystkich plików w hierarchii i uniq
wyświetla tylko te katalogi, które pojawiają się co najmniej dwa razy.
find
. W tym przypadku, ponieważ GNUfind
będzie zmieniać nazwy katalogów, które mają znaki, których nie można wydrukować w bieżących ustawieniach narodowych (takich jak „ä” w ustawieniach regionalnych C). Zobacz także unix.stackexchange.com/questions/321697/…-printf '%h\0' | sort -z | uniq -zd | xargs -r0 ...
Spowoduje to znalezienie wszystkich nazw w bieżącym katalogu lub pod nim, a następnie odfiltrowanie wszystkich nazw, które nie są nazwami katalogów.
Pozostałe nazwy katalogów zostaną podane temu krótkiemu skryptowi:
Ten skrypt policzy liczbę zwykłych plików (pomijając dowiązania symboliczne) w katalogu podanym jako pierwszy argument wiersza poleceń (od
find
). Ostatnie polecenie w skrypcie jest testem sprawdzającym, czy liczba wynosiła 2 lub więcej. Wynikiem tego testu jest wartość zwracana (status wyjścia) skryptu.Jeśli test się powiedzie,
-print
spowodujefind
wydrukowanie ścieżki do katalogu.Aby uwzględnić również ukryte pliki (pliki, których nazwy zaczynają się od kropki), zmień
sh -c
skrypt w powiedzeniudo
Testowanie:
źródło
[ "" -ge 2 ]
jest to prawidłowy test.dash
,bash --posix
itest
wszystkie wyświetlają komunikat o błędzie i wychodzą z 2 (tzn. „Wystąpił błąd”)ksh
działa jako massh
. Poprawi się natychmiast. Dzięki za szturchanie mnie! :-)[ -f ... ]
wyklucza dowiązania symboliczne. Powinieneś dodać test, aby je wyeliminować, ponieważ pytanie określa, że należy liczyć tylko zwykłe pliki.Z pomocą odpowiedzi Gillesa na SU i jej odwrotnej kolejności oraz modyfikacji, oto czego potrzebujesz.
Drzewo katalogów.
Wynik:
źródło
test
idir2
katalogi w mojej konfiguracji testowej (patrz moja odpowiedź).test/x1
itest/x2
jako pliki również ...$1
i$2
będą katalogami dlatest
, a katalog zostanie pominięty.Inne podejście
find
+wc
:path/currdir
- ścieżka do twojego bieżącego katalogu-maxdepth 1
- rozważ tylko bezpośrednie podfoldery podrzędne! -empty
- ignoruj puste podfoldery! -path "path/currdir"
- zignoruj bieżącą ścieżkę katalogucount=$(find "$1" -maxdepth 1 -type f | wc -l)
-count
jest przypisany z liczbą plików dla każdego znalezionego podfolderu[ $count -ge 2 ] ... -print
- wydrukuj nazwę / ścieżkę podfolderu zawierającą 2 lub więcej zwykłych plikówźródło