Finden Sie Dateien in mehreren Ordnernamen

44

Ich versuche, alle Dateien von dir1, aufzulisten dir2, dir3und dir4die sich möglicherweise irgendwo in meinem Unterverzeichnis befinden, wenn ich cwdden findBefehl verwende. Ich habe folgendes ohne Erfolg versucht:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

Ich habe es auch versucht posix-extended. Wie kann ich diese Dateien auflisten?

Aaron
quelle
finden . -type f -regextype sed -regex ". * / dir [1-4] / [a-z0-9] *" .. kürzeste Antwort bisher :) siehe Antwort unten .. unix.stackexchange.com/a/390333 / 242983
alpha_989

Antworten:

59

Und wenn Sie wollen drei Ordner mit dem Namen suchen foo, barund bazfür alle *.pyDateien, verwenden Sie diesen Befehl:

find foo bar baz -name "*.py"

Also, wenn Sie Dateien von der dir1 dir2 dir3Verwendung anzeigen möchtenfind dir1 dir2 dir3 -type f

Versuche dies find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;

harish.venkat
quelle
Ich hätte es klarstellen sollen. Ich habe möglicherweise nicht den Pfad zu den Dateien, die ich durchsuchen möchte. Ich weiß nur, dass es sich um Unterverzeichnisse des aktuellen Verzeichnisses handelt.
Aaron
Verwenden Sie ./diranstelle vondir
harish.venkat
Das Verzeichnis müsste sich jedoch immer noch im CWD befinden. Es kann zwei Ebenen niedriger sein (z. B. ./path/to/dir1). In diesem Fall ./dir1würde es nicht existieren.
Aaron
hat die Antwort bearbeitet.
harish.venkat
8

Verwenden Sie am besten die -path-Direktive:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

Das heißt: Finden Sie alle Dateien im aktuellen Verzeichnis, in denen sich "dir1" oder "dir2" oder "dir3" oder "dir4" im Pfad befindet.

Regelmäßige Wartung
quelle
Du hast die Klammer an der falschen Stelle. Siehe auch -aund -ofür das Standardäquivalent von GNU's -and/ -or.
Stéphane Chazelas
4

Nur um es allen mitzuteilen. Das Hinzufügen .*/vor jedem dirlöste das Problem, da das regexmit dem vollen Pfad übereinstimmt, wie es scheint.

Aaron
quelle
3

Dies ist meine erste Idee, nachdem ich die vorherigen Antworten gelesen habe:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

Dies berücksichtigt, dass der reguläre Ausdruck mit dem gesamten Dateinamen übereinstimmen muss und leichter zu verstehen ist.

Ronin Tom
quelle
2

Ein Beispiel für das schnelle (!) Auffinden bestimmter Dateien (access_log) an mehreren Speicherorten, die durch Platzhalter (Home-Verzeichnis) und allgemeines Apache2-Protokollverzeichnis definiert sind. Dabei wird auch eine Namensfilterung angewendet, um SSL-Protokolle und komprimierte alte Protokolle auszuschließen. Beantwortet die Frage hier nicht direkt, ist aber möglicherweise hilfreich für jemanden, der diese Anweisungen gefunden hat (wie ich).

find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

Seien Sie vorsichtig mit Leerzeichen, besonders in der Nähe von \(und \).

Ich habe es übrigens für apachetop verwendet, um die aktivsten Websites auf meinem Server zu finden.

apachetop -d1 -s9 -p $(find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)
Kristjan Adojaan
quelle
2

Sie müssen nicht dir1 bis dir4 nach Namen angeben, wenn Sie regextype verwenden

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: finde Dateien nicht Verzeichnisse
  • regextype sed: benutzt sed regextype
  • regex: Sucht mit Regex im gesamten Pfad
  • ".*/dir[1-4]/[a-z0-9]*":. * am Anfang bedeutet eine beliebige Anzahl von Zeichen, die vom Typ sein können (char / number / backslash (/) etc); dir [1-4] bedeutet suche nach "dir" gefolgt von einer Zahl zwischen 1 und 4; / [^ /] * gibt an, dass nach dir1-4 alle Pfadnamen weggelassen werden, die / enthalten, sodass nur Dateien im Verzeichnis dir1-dir4 zurückgegeben werden und alle Unterverzeichnisse ignoriert werden, die sich möglicherweise in dir1-dir4 befinden.

hat ein Verzeichnis zum Testen erstellt: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017

alpha_989
quelle
(1) Möglicherweise kennen wir Aarons genaue Situation oder Anforderungen nie, aber andere Antworten haben die vorsichtige Entscheidung getroffen, dass er über vier Verzeichnisse verfügt, deren Namen nicht spezifiziert sind. (Sie könnten red, green, blueund yellow, oder sie könnten sein John, Paul, Georgeund Ringo.) Ihre Antwort geht davon aus, dass sie buchstäblich dir1 , dir2, dir3und dir4. … (Fortsetzung)
Scott
(Fortsetzung)… (2) Warum nehmen Sie an, dass Aaron keine Unterverzeichnisse durchsuchen möchte? Er scheint zu sagen, dass er es tut. (3) Warum beschränken Sie die Suche auf Dateien , deren Namen nur Kleinbuchstaben und Ziffern (ohne Dinge wie foo_bar, foo.txtund FOO)? (4) Warum erklärt Ihr Text, /[^/]*wenn Ihre Antwort ihn nicht verwendet?
Scott
Hallo Scott, das ist für deinen Kommentar.
Alpha_989
(1-3). Er erwähnt, dass "ich versuche, alle Dateien von dir1, dir2, dir3 und dir4 aufzulisten ", die sich irgendwo in einem Unterverzeichnis meiner cwd befinden könnten, was bedeutet, dass dir1-dir4 sich irgendwo befinden könnte, aber er möchte die richtige Datei finden in dir1-dir4. Natürlich, wenn es nicht dir1-dir4 ist, müssen Sie es mit rot \ | blau \ | grün \ | in die spezifischen Namen ändern etc ..
alpha_989
4. Tippfehler da .. Ich habe [a-z0-9] * verwendet, bevor ... dann wurde mir klar, dass [^ /] * kürzer und umfassender ist ... vergiss es zu ändern, als ich dies gepostet habe. Vielen Dank für Ihre sorgfältigen Kommentare.
Alpha_989
0

Ich weiß, dass Sie dies mit find angegeben haben, aber nur um andere Optionen anzuzeigen, die verwendet werden können, können Sie xargs verwenden:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

Sie können eine Datei mit dem Namen "folders" haben, die Folgendes enthält:

$ cat folders
dir1
dir2
dir3
dir4

Dann können Sie so etwas tun:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

xargs meiner meinung nach fühle ich mich vielseitiger als find -exec. Sie können auch ein paar verrückte Sachen wie machen

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
Cuauhtli
quelle