Wie kann ich alle Dateien auflisten, aber nur in Verzeichnissen, die keine Unterverzeichnisse haben?

Wie kann ich alle Dateien auflisten, aber nur in Verzeichnissen, die keine Unterverzeichnisse haben?

Ich habe einen Verzeichnisbaum, in dem ich rekursiv nach allen Dateien eines bestimmten Typs (beispielsweise allen .jpg) suchen möchte, ich möchte diese Dateien aber nur auflisten, wenn sie sich am unteren Ende eines Verzeichnisbaums befinden.

Mein Baum sieht beispielsweise so aus:

                          home
                          root
                   f1     f2     f3
                   f11    f22    f33
                   f111   f222   f333

und alle Ordner haben 's, ich möchte nur die 's in / / usw. .jpgauflisten und die in den übergeordneten Ordnern ignorieren..jpgf111f222f333

Ich weiß, dass ich einen Suchbefehl (wie find . -name "*.jpg") verwenden kann, um eine Liste aller .jpg's im gesamten Baum zu erhalten, aber ich bin nicht sicher, wie ich sie auf die untersten Ordner beschränken kann, ohne etwas wie 'ing die Ergebnisse so zu gestalten, dass sie nach / / 's grepfiltern, was nicht wirklich machbar ist, da ich Hunderte von Ordnern habe und nicht weiß, wie die Ordner der letzten Ebene für alle einzeln heißen könnten.111222333

Antwort1

Dies können Sie in zwei Schritten tun:

find . -type d -links 2 -print0 | xargs -0 -I{} find {} -name \*.jpg

Der erste Befehl listet alle Verzeichnisse ohne Unterverzeichnisse auf (da jedes Unterverzeichnis einen Link zur Linkanzahl hinzufügt, während ein leeres Verzeichnis zwei hat). Der zweite Befehl wird findfür jedes dieser Ergebnisse manuell aufgerufen.

Antwort2

Ein POSIX-Äquivalent von@TomHunts Lösung.

find . -type d -links 2 -exec sh -c '
  find "$@" -type f -name "*.jpg"' sh {} +

Dies -links 2beruht auf der Eigenschaft einiger Dateisysteme, dass die Linkanzahl von Verzeichnissen (anfangs 2 für den Eintrag in ihrem übergeordneten Verzeichnis und den .Eintrag in sich selbst) für jedes Unterverzeichnis um eins erhöht wird (aufgrund des ..Eintrags in ihnen). Einige moderne Dateisysteme wie btrfsoder nilfs, deren Strukturen radikal anders sind, verfügen jedoch nicht über eine solche Eigenschaft.

Mit zshkönnten Sie beispielsweise Folgendes tun:

has_subdirs() {
  local l
  l=($REPLY/*(/DNoN[1]))
  (($#l))
}
dirs_without_subdirs=(**/*(DN^+has_subdirs))
jpgs=($^dirs_without_subdirs/*.jpg(ND.))
(($#jpgs)) && printf '%s\n' $jpgs

verwandte Informationen