• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Mit "tree" ausgewählte Verzeichnisse ohne Inhalt auflisten

Rumcajs

Member
Hallo Forum,

ich habe ein Problem mit dem Befehl "tree".
"tree" finde ich gut, weil er schön übersichtlich die Verzeichnisstruktur darstellt.
Üblicherweise wird "tree" verwendet, um Dateien aufzulisten.
Ich möchte aber nur Verzeichnisse auflisten die in ihrem Namen einen bestimmten Text enthalten ohne(!) die enthaltenen Dateien.

Der Befehlt "tree -d>Verzeichnisliste.txt" listet alle Verzeichnisse auf ohne die enthaltenen Dateien.
Mit dem Befehlt "tree --prune -P "*text*" --matchdirs>Textverzeichnisse.txt" schaffe ich es, nur die gewünschten Verzeichnisse aufzulisten. Aber es sind alle enthaltenen Dateien mit in der Liste.
Wenn ich diesen Befehl mit " -d " kombiniere, funktioniert die Auswahl nicht mehr. Diese Kombination scheint nicht möglich.

Kennt Ihr eine Lösung für das Problem?

Vielen Dank im Voraus für Eure Hilfe.
 

marce

Advanced Hacker
man tree meint
Code:
       --matchdirs
              If a match pattern is specified by the -P option, this will cause the pattern to be applied  to  direc‐
              tory names (in addition to filenames).  In the event of a match on the directory name, matching is dis‐
              abled for the directory's contents. If the --prune option is used, empty folders that match the pattern
              will not be pruned.
könnte Dein Problem lösen.
 

harley

Hacker
Option -P sucht innerhalb der Dateinamen.
Option --matchdirs weitet die Suche auf Verzeichnisse aus. Dort wird nicht mehr nach Dateien gesucht, sie werden aber angezeigt.
Option --prune blendet Verzeichnisse ohne Fundstellen aus und verträgt sich nicht mit …
Option -d, welche nur Verzeichnisse anzeigt

mein Tipp …
Code:
tree --prune --matchdirs -P "*Rumcajs*"

… hilft nur insofern, dass trotzdem alle Dateien angezeigt werden. Mit ›tree‹ alleine wirst Du da nicht weiterkommen.

harley :-D
 
OP
R

Rumcajs

Member
Wenn ich den Befehl "tree -P "*text*" -- matchdirs>Liste.txt" eingebe, werden alle(!) Verzeichnisse aufgelistet.
Auch solche, die *text* nicht enthalten. Bei denen, die *text* enthalten, werden die enthaltenen Dateien aufgelistet.
Also, so gesehen, funktioniert das "--matchdirs" nicht (zumindest nicht so, wie ich es verstehe).

Mit dem Zusatz "--prune" werden nur die Verzeichnisse gelistet, die *text* enthalten. Aber auch mit allen Dateien.
 
OP
R

Rumcajs

Member
harley schrieb:
... Mit ›tree‹ alleine wirst Du da nicht weiterkommen.
harley :-D

Es müsste nur möglich sein, die Parameter "--matchdirs" und "-d" kombinieren zu können.
Das geht wohl nicht, weil "--matchdirs" unbedingt Dateien ausgeben will, was mit "-d" unterbunden werden soll.
Aber eigentlich will ich mit "--matchdirs" doch nur Verzeichnisse auswählen, gar keine Dateien. :irre:
 

josef-wien

Ultimate Guru
Rumcajs schrieb:
Verzeichnisse auflisten die in ihrem Namen einen bestimmten Text enthalten
Wenn Du nicht auf tree bestehst, sollte
Code:
find / -type d -name *text* 2>/dev/null | sort
Deine Anforderung erfüllen. Statt / kannst Du auch mit einem anderen Verzeichnis beginnen. 2>/dev/null verhindert Fehlermeldungen für Verzeichnisse, für die Du keine Berechtigung hast.
 

harley

Hacker
Oder wenn Du ›find‹ auch nicht möchtest, kann das helfen:

Code:
ls -R | grep ^[.] | grep text

:-D
 

harley

Hacker
Rumcajs schrieb:
Es müsste nur möglich sein, die Parameter "--matchdirs" und "-d" kombinieren zu können.
Das geht wohl nicht, weil "--matchdirs" unbedingt Dateien ausgeben will, was mit "-d" unterbunden werden soll.
Aber eigentlich will ich mit "--matchdirs" doch nur Verzeichnisse auswählen, gar keine Dateien. :irre:

Nein. "--matchdirs" weitet die Suche von "-P" auf Verzeichnisse aus. "-d" beißt sich eher mit "-P". Du kannst also nicht beides gleichzeitig haben. :-D
 
OP
R

Rumcajs

Member
harley schrieb:
Nein. "--matchdirs" weitet die Suche von "-P" auf Verzeichnisse aus. "-d" beißt sich eher mit "-P". Du kannst also nicht beides gleichzeitig haben. :-D
Das kann man so nicht sagen.

Ich habe noch ein paar Versuche gemacht und möchte es mal so beschreiben:
Der Schwerppunkt des Befehls "tree" ist die Ausgabe von Dateien(!) mit Verzeichnisbaum. Er ist nicht für die Darstellung eines Verzeichnisbaums.
(Aber das ist es, was ich eigentlich will und was - leider - so scheinbar nicht funktioniert.)

1.) Der Befehle "tree -p "*text*">Textliste.txt" gibt alle(!) Verzeichnisse aus und die Dateien die *text* enthalten.
2.) Der Befehl "tree -p "*text*" --matchdirs>Textliste.txt" gibt alle(!) Verzeichnisse aus und die Dateien die *text* enthalten und zusätzlich alle Dateien (egal ob mit oder ohne *text*), deren Verzeichnisname *text* enthält.
3.) Der Befehl "tree -p "*text*" --matchdirs --prune>Textliste.txt" gibt alle Verzeichnisse aus, die Dateien mit *text* enthalten, diese Dateien, die *text* enthalten und zusätzlich alle Verzeichnisse die *text* enthalten mit allen Dateien (egal ob mit oder ohne *text*).
4.) Der Befehl "tree -p "*text*" --matchdirs --prune -d>Textliste.txt" gibt exakt das gleiche aus wie "tree -d>Textliste.txt". Das heißt, "-p "*text*" --matchdirs --prune" wird komplett ignoriert.
(Die größte Datei ergibt Fall 2.)

Der Fall 4.) ist der, der mich interessiert, aber nicht funktioniert.
Nur die Ausgabe von Verzeichnissen (bzw. Verzeichnisbäumen) ist eben nicht das Ding von "tree".
 

abgdf

Guru
Also, ich hab' mir gerade schön den Kopf darüber zerbrochen.
Wollte dieses Perl-Skript so umschreiben, daß es das macht, was Du willst. War aber nicht so einfach, dazu unten.

"--matchdirs" scheint relativ neu zu sein, ist also auch noch in der Entwicklung, da kann sich noch was ändern.
Ich hab' mir erstmal die aktuelle Version von tree gezogen und kompiliert ("CFLAGS=-std=c99 " mußte im Makefile ergänzt werden).

Nun zum Problem: Die aktuelle Version von tree hat eine Option "--fromfile".
Man kann sich also mit
Code:
find . -type d > tempfile
die Verzeichnisse ausgeben lassen. Dann kann man mit "grep" die Zeilen mit dem Suchstring daraus herausfiltern. Und dann
Code:
tree --fromfile tempfile
einsetzen. Voilà.
Das kann man natürlich alles in ein Skript packen, und dann mit nur einem Befehl aufrufen. Das tempfile kann man im Skript ja auch wieder löschen, wenn es da nicht rumliegen soll.

----

Perl: Da muß ich letztlich von @a nach @b, und das ist nicht so einfach:
Code:
my @a = (".",
         "./b",
         "./a",
         "./a/c",
         "./a/d",
         "./a/d/f",
         "./a/d/e",
         "./a/d/g");

my @b = ('.', ['b'], ['a', ['c'], ['d', ['f'], ['e'], ['g']]]);

-----

Nochmal genauer: Das Problem ist folgendes: Da läuft ein "find" über die Verzeichnisse. Du hast meinetwegen:
Code:
./a/b/c/suchstring/d
Woher soll das Programm jetzt wissen, daß Du auch
Code:
./a/b/c
haben willst, wenn der Suchstring darin gar nicht enthalten ist?
Und vor allem, daß Du gleichzeitig
Code:
./a/b/c/e
nicht haben willst.

Ich merke gerade, meine "Lösung" oben löst das Problem auch nicht. Oje. :)

Edit: Na ja, man könnte sicher ein Perl-Skript machen, das das "grep" integriert und gleichzeitig den Baum wieder hochgeht, und die übergeordneten Verzeichnisse wieder hinzufügt. Nicht unmöglich ...
Aber dieses "--fromfile" ist das schon nützlich.
 

abgdf

Guru
Scheint auch so zu gehen:
Code:
find . -type d -printf "%p/\n" | grep searchstring | tree --fromfile
"Geht nicht, gibt's nicht." :p
 

Christina

Moderator
Teammitglied
abgdf schrieb:
Also, ich hab' mir gerade schön den Kopf darüber zerbrochen.
Ich habe das jetzt auch ausprobiert:
Aktuelle Version von tree laden: http://mama.indstate.edu/users/ice/tree/
Code:
tar xvzf tree-2.0.2.tgz
cd tree-2.0.2/
sed '/^CFLAGS/s/$/ -std=c99/' Makefile > Makefile.edited && mv -f Makefile.edited Makefile
make
sudo make install
anschließend der Test
(etwas abgeändert, damit bei Unter-Unterverzeichnissen ohne den searchstring keine Ausgabe erfolgt):
Code:
find searchdir/ -type d -name '*searchstring*' -printf "%p/\n" | tree --fromfile
…funktioniert!
 
Rumcajs schrieb:
Kennt Ihr eine Lösung für das Problem?
Jetzt teste du das mal.
 
Oben