PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Skript-Problem: Wie Verzeichnisbaum parsen?



sruggiero
25.02.09, 09:29
Hallo,

ich möchte in einem Skript einen großen Verzeichnisbaum parsen, dazu muss ich aus dem Baum eine Liste mit den Pfaden zu allen "tiefsten" Verzeichnissen erstellen. D.h. ich brauchen einen Befehl, der in den Baum einsteigt und in das erste Unterverzeichnis geht, dort wieder das nächste Unterverzeichnis usw. bis kein Unterverzeichnis mehr kommt und dann den vollständigen Pfad zum letzten Unterverzeichnis ausgibt.
Dann geht es ein Verzeichnis hoch und in das nächste Unterverzeichnis rein, dort dann das gleiche Spiel.

Dabei kann ich vorher nicht wissen, wie tief jeder Teilbaum ist.

Zur Veranschaulichung:

Dieser Baum:



root
---Dir1
--- ---Subdir1ofDir1
--- --- ---DirA
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3
--- --- ---DirB
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3
--- ---Subdir2ofDir1
--- --- ---DirC
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3
--- ---Subdir3ofDir1
--- --- ---DirD
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3
--- --- ---DirE
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3
---Dir2
--- ---Subdir1ofDir2
--- --- ---DirF
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3
--- --- ---DirG
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3
--- ---Subdir2ofDir2
--- --- ---DirH
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3
--- --- ---DirI
--- --- --- ---File1
--- --- --- ---File2
--- --- --- ---File3


soll aufgelöst werden in diese Liste:



/Dir1/Subdir1ofDir1/DirA
/Dir1/Subdir1ofDir1/DirB
/Dir1/Subdir2ofDir1/DirC
/Dir1/Subdir3ofDir1/DirD
/Dir1/Subdir3ofDir1/DirE
/Dir2/Subdir1ofDir2/DirF
/Dir2/Subdir1ofDir2/DirG
/Dir2/Subdir2ofDir2/DirH
/Dir2/Subdir2ofDir2/DirI


der "find"-Befehl gibt mir immer auch alle "Zwischenverzeichnisse" aus, die Liste sieht dann so aus:



find <root> -type d

/
/Dir1
/Dir1/Subdir1ofDir1
/Dir1/Subdir1ofDir1/DirA
/Dir1/Subdir1ofDir1/DirB
/Dir1/Subdir2ofDir1
/Dir1/Subdir2ofDir1/DirC
/Dir1/Subdir3ofDir1
/Dir1/Subdir3ofDir1/DirD
/Dir1/Subdir3ofDir1/DirE
/Dir2
/Dir2/Subdir1ofDir2
/Dir2/Subdir1ofDir2/DirF
/Dir2/Subdir1ofDir2/DirG
/Dir2/Subdir2ofDir2
/Dir2/Subdir2ofDir2/DirH
/Dir2/Subdir2ofDir2/DirI


Kann mir da jemand helfen?

Vielen Dank!

Schönen Gruss,

Stephan

marce
25.02.09, 09:48
wenn die Struktur immer gleich ist - mindepth bei find

Ansonsten z.B. eine Kombination aus find -type f (findet alle Dateien) dirname und sort -u

sruggiero
25.02.09, 10:25
Hallo,


wenn die Struktur immer gleich ist - mindepth bei find

das geht leider nicht, da ich die Tiefe des Baumes vorher nicht kenne...


Ansonsten z.B. eine Kombination aus find -type f (findet alle Dateien) dirname und sort -u

Das verstehe ich nicht. "find -type f" gibt mir ja auch die Dateien aus, ich will aber nur die Verzeichnisse (also "-type d", wie oben beschrieben, oder?) - und wie geht das mit "sort -u"? Wenn ich das find-Ergebnis in sort pipe, kommt es unverändert wieder raus (find geht ja alphabetisch durch den Baum, und jede Ergebniszeile kommt auch nur 1x vor)...

marce
25.02.09, 10:28
find . -type f -exec dirname {} ';' | sort -u
liefert Dir eine Liste aller Verzeichnisse, in denen Dateien enthalten sind.

sruggiero
25.02.09, 10:38
Alles klar, so hat's funktioniert - Danke schön!!
:)


Edit:

Ich habe noch eine andere Möglichkeit erfahren:


#!/bin/bash

IFS=$'\n'

function dive_into_subdir {
count=$(find "$1" -type d -mindepth 1| wc -l)
if [ "$count" -eq 0 ]
then
echo $1
else
for dir in $(find "$1" -type d -mindepth 1)
do
dive_into_subdir "$dir"
done
fi
}

dive_into_subdir "$1"


Die Ausgabe dieses Skripts nach "sort -u" pipen, das ergibt eine Liste der "Spitzen der Zweige" des Verzeichnisbaums, und zwar auch dann, wenn in einem der Zwischenverzeichnisse eine Datei (und nicht nur Unterordner) liegt.