Suchen Sie nach Dateien, die den gleichen Namen wie das Verzeichnis haben

Suchen Sie nach Dateien, die den gleichen Namen wie das Verzeichnis haben

Ich habe folgendes Problem:

Das Verzeichnis Example1enthält drei Dateien: Example1, Thingsund Pictures.

Das Verzeichnis Example2enthält drei Dateien: Example2, Example3und Pictures.

Ich brauche eine Liste, die nur die Dateien anzeigt, die mit dem Verzeichnisnamen übereinstimmen. Dies sind: Example1und Example2. Ich habe es mit diff, find, locate und ls versucht ... aber ich habe nichts erreicht.

Antwort1

Sie können Dateinamen, die denselben Namen wie das enthaltene Verzeichnis haben, problemlos mit einem Regex abgleichen, der eine Rückverweis verwendet. Dies sind Dateinamen der Form, what/ever/something/somethingbei denen die beiden somethingTeile identisch sind und keinen Schrägstrich enthalten. In der BRE-Regex-Syntax [^/]*entspricht dies jeder Zeichenfolge, die keinen Schrägstrich enthält, \(/[^/]*\)entspricht einem Schrägstrich, gefolgt von einer beliebigen Anzahl von Zeichen, die kein Schrägstrich sind, und macht das Ganze zu einer Gruppe, und \1entspricht demselben Text, der von der ersten Gruppe abgeglichen wird, \(/[^/]*\)\1entspricht also zwei Pfadsegmenten mit demselben Namen. Fügen Sie .*am Anfang hinzu, um die vorherigen Verzeichniskomponenten abzugleichen.

Mit GNU find, FreeBSD find, macOS find oder allen anderen, finddie Folgendes unterstützen -regex:

find . -regex '.*\(/[^/]*\)\1'

Antwort2

Da es im Allgemeinen weniger Verzeichnisse als Dateien gibt, suchen wir nach allen Verzeichnissen und testen anschließend, ob sie den erforderlichen Dateinamen enthalten.

find . -type d -exec sh -c '
    for dirpath do
        filepath="$dirpath/${dirpath##*/}"
        [ -f "$filepath" ] && printf "%s\n" "$filepath"
    done' sh {} +

Dadurch werden die Pfadnamen aller regulären Dateien (und symbolischen Links zu regulären Dateien) gedruckt, die sich in einem Verzeichnis mit demselben Namen wie die Datei befinden.

Der Test wird in einem kurzen Inline- sh -cSkript durchgeführt, das eine Reihe von Verzeichnispfadnamen als Argumente erhält. Es durchläuft jeden Verzeichnispfadnamen und erstellt einen Dateipfadnamen mit dem gesuchten Namen. Das ${dirpath##*/}im Code könnte durch ersetzt werden $(basename "$dirpath").

Für die angegebene Beispielverzeichnisstruktur würde dies ausgeben:

./Example1/Example1
./Example2/Example2

Um einfach zu testen,jeder Name, nicht nur normale Dateien, ändern Sie den -fTest in einen -eTest.

Antwort3

Verwenden find -exec:

find . -type f \
  -exec sh -c '[ "$(basename "$1")" = "$(basename "$(dirname "$1")")" ]' find-sh {} \; \
  -print

Die -printAusführung erfolgt nur, wenn das Ergebnis darin [ ... ]wahr -exec sh -c '...'ist.

Ausgabe:

./Example1/Example1
./Example2/Example2

verwandte Informationen