find . -type d -execdir sh -c ' [ "$(find "$1" -maxdepth 1 -type f -name "*.txt" -print -quit | wc -l)" -gt 0 ] && [ "$(find "$1" -maxdepth 1 -type f ! -name "*.txt" -print -quit | wc -l)" -eq 0 ] ' find-sh {} \; -print
Die äußeren find
Versorgungsverzeichnisse werden geprüft. Zwei innere find
-s prüfen, ob sich im Verzeichnis mindestens eine .txt
Datei und keine Nicht- .txt
Dateien befinden. sh
Shell implementiert Logik mit [ … ]
und &&
.
Anmerkungen:
-maxdepth
wird von POSIX nicht benötigt. Zum POSIX-Ansatz siehe diese Frage .-quit
wird von POSIX nicht benötigt. Diese Aktion wirdfind
beendet, sobald eine übereinstimmende Datei gemeldet wird. Dies ist nützlich, da wir höchstens eine übereinstimmende Datei benötigen, um das Ergebnis zu erhalten,wc -l
und[ … ]
wenn Sie das Programm frühzeitig beenden, sparen Sie Zeit. Ohne-quit
den gesamten Befehl funktioniert es nur, wenn viele Dateien vorhanden sind. Alternativ können Sie verwendenfind … | head -n 1 | wc -l
; In diesem Fallhead
wird die Pipe nach der ersten gefundenen Datei beendet,wc
das Ergebnis wird sofort angezeigt, siefind
wird jedoch nur dann erkannt, wenn die Pipe (wenn) versucht, eine weitere Zeile zu schreiben . Und es ist ein Kompromiss:head
Vielleicht sparen Sie Zeit und Ressourcen, aber (als separater Prozess) benötigt es Zeit und Ressourcen, um zweimal in jedem Verzeichnis erzeugt zu werden.- Pfade mit Zeilenumbrüchen (falls vorhanden) täuschen,
wc -l
aber es spielt keine Rolle, da diese zusätzlichen Zeilenumbrüche möglicherweise nur dann zu der Zählung beitragen, wenn die "richtige" Anzahl ohnehin ungleich Null ist und wir nur wissen müssen, ob das Ergebnis Null ist oder nicht .