Antworten:
Hier ist ein völlig anderer Ansatz basierend auf GNU findund uniq. Dies ist viel schneller und viel CPU-freundlicher als Antworten, die auf der Ausführung eines Shell-Befehls basieren, der Dateien für jedes gefundene Verzeichnis zählt.
find . -type f -printf '%h\n' | sort | uniq -d
Der findBefehl druckt das Verzeichnis aller Dateien in der Hierarchie und uniqzeigt nur die Verzeichnisse an, die mindestens zweimal angezeigt werden.
-printf '%h\0' | sort -z | uniq -zd | xargs -r0 ...
find . -type d \
-exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' \
-print
Dadurch werden alle Namen im oder unter dem aktuellen Verzeichnis gefunden und anschließend alle Namen herausgefiltert, die keine Namen von Verzeichnissen sind.
Die verbleibenden Verzeichnisnamen werden diesem kurzen Skript zugewiesen:
c=0
for n in "$1"/*; do
[ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
done
[ "$c" -ge 2 ]
Dieses Skript zählt die Anzahl der regulären Dateien (Überspringen symbolischer Links) in dem Verzeichnis, das als erstes Befehlszeilenargument (von find) angegeben wurde. Der letzte Befehl im Skript ist ein Test, um festzustellen, ob die Anzahl 2 oder höher war. Das Ergebnis dieses Tests ist der Rückgabewert (Exit-Status) des Skripts.
Wenn der Test erfolgreich war, -printwird findder Pfad zum Verzeichnis ausgedruckt.
Um auch versteckte Dateien (Dateien, deren Namen mit einem Punkt beginnen) zu berücksichtigen, ändern Sie das sh -cSkript von "sagen"
for n in "$1"/*; do
zu
for n in "$1"/* "$1"/.*; do
Testen:
$ tree
.
`-- test
|-- a
|-- dir1
| |-- a
| |-- b
| `-- c
`-- dir2
|-- dira
|-- dirb
| |-- file-1
| `-- file-2
`-- dirc
6 directories, 6 files
$ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' -print
./test/dir1
./test/dir2/dirb
[ "" -ge 2 ]ein gültiger Test ist.
dash, bash --posixUnd testalle Display eine Fehlermeldung und Ausgang mit 2 (dh „Ein Fehler ist aufgetreten“)
kshdas als läuft sh. Wird sofort geändert. Danke, dass du mich angestupst hast! :-)
[ -f ... ]dereferenziert symbolische Links. Sie sollten einen Test hinzufügen, um sie zu beseitigen, da die Frage angibt, dass nur reguläre Dateien gezählt werden sollen.
Mit Hilfe von Gilles 'Antwort auf SU und seiner Umkehrung und einigen Modifikationen, hier was Sie brauchen.
find . -type d -exec sh -c 'set -- "$1"/*;X=0;
for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ {} \; -print
Verzeichnisbaum.
.
├── test
│ ├── dir1
│ │ ├── a
│ │ ├── b
│ │ └── c
│ ├── dir2
│ │ ├── dira
│ │ │ └── a file\012with\012multiple\012line
│ │ ├── dirb
│ │ │ ├── file-1
│ │ │ └── file-2
│ │ └── dirc
│ ├── diraa
│ ├── dirbb
│ ├── dircc
│ └── x
│ └── x1
│ └── x2
└── test2
├── dir3
└── dir4
Ergebnis:
./test
./test/dir1
./test/dir2/dirb
testals auch das dir2Verzeichnis in meinem Testaufbau (siehe meine Antwort).
test/x1und test/x2als Dateien hinzu ... $1und $2werden Verzeichnisse für test, und das Verzeichnis wird übersehen.
Ein weiterer find+ wcAnsatz:
find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" \
-exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ {} \; -print
path/currdir - Pfad zu Ihrem aktuellen Verzeichnis
-maxdepth 1- Berücksichtigen Sie nur direkte untergeordnete Unterordner
! -empty - leere Unterordner ignorieren
! -path "path/currdir" - Ignorieren Sie den aktuellen Verzeichnispfad
count=$(find "$1" -maxdepth 1 -type f | wc -l)- countwird mit der Anzahl der Dateien für jeden gefundenen Unterordner zugewiesen
[ $count -ge 2 ] ... -print - Drucken Sie den Namen / Pfad des Unterordners, der 2 oder mehr reguläre Dateien enthält
find. In diesem Fall, weil GNUfinddie Namen von Verzeichnissen mit Zeichen entstellt, die im aktuellen Gebietsschema nicht druckbar sind (wie "ä" im Gebietsschema C). Siehe auch unix.stackexchange.com/questions/321697/…