Welches Tool zum Zeichnen eines Dateibaumdiagramms [geschlossen]

87

Wie würden Sie bei einem gegebenen Dateibaum - einem Verzeichnis mit Verzeichnissen usw. - ein Skript schreiben, um ein Diagramm des Dateibaums als Grafikdatei zu erstellen, die ich in ein Textverarbeitungsdokument einbetten kann? Ich bevorzuge Vektordateien (SVG, EPS, EMF ...). Das Tool muss unter Windows ausgeführt werden, vorzugsweise jedoch plattformübergreifend. Das Werkzeug kann kommerziell, aber vorzugsweise kostenlos sein.

Update 2012-02-20. Die Frage bezog sich auf ein Dokumentationsunterprojekt. Ich musste erklären, wo sich Dateien (insbesondere Ressourcen und Konfigurationsdateien) befinden. Am Ende habe ich den Befehl dos tree verwendet. Ich habe sowohl das Ergebnis auf dem Bildschirm (für kurze Ordner) als auch für längere Ordner auf eine Textdatei umgeleitet, die ich dann bearbeitet habe. Wenn zum Beispiel ein Unterordner 20 ähnlich typisierte Dateien enthielt, die für den Punkt, den ich machte, einzeln nicht wichtig waren, ließ ich nur zwei übrig und ersetzte den Rest durch eine ... Zeile. Ich druckte die Datei dann erneut aus, um sie zu konsolidieren, und der Bildschirm griff danach. Vor dem Aufnehmen des Bildschirms musste ich die Vordergrundfarbe in Schwarz und die Hintergrundfarbe in Weiß ändern, um besser auszusehen und Tinte in einem Dokument zu sparen, falls dieses gedruckt werden sollte.

Es ist sehr überraschend, dass es kein besseres Werkzeug dafür gibt. Wenn ich Zeit hätte, würde ich eine Visio-Erweiterung schreiben oder eine Befehlszeile sein, die SVG erzeugt. SVG ist HTML5-minderwertig und würde sogar die schmerzlose Aufnahme in die Online-Dokumentation ermöglichen.

Update 2017-10-17. Es tut mir leid, dass diese Frage entfernt wurde, da sie nicht zu SO gehört. Also habe ich es umformuliert. Ich brauche ein Skript - kein WYSIWYG-Tool. Jede Skriptsprache oder Bibliothek ist also in Ordnung. Es ist also eine Frage zum Schreiben von Code, und ich glaube, sie gehört zu SO.

Michael
quelle
10
Warum ist diese Frage geschlossen? Es gibt Programmier-DSLs zum Zeichnen von Bäumen: zB Tools wie graphviz, die dies "programmatisch" lösen können.
Piotr Lesnicki
5
Ich werde dies (vorläufig) wieder öffnen, denn wenn es ein einfaches "Wie zeige ich, was auf dem Bildschirm ist" wäre, hätte er nach einem Screen Grabber gefragt. Wenn er es zeichnen möchte, ist es wahrscheinlich für ein Designdokument oder eine Präsentation, daher wird er irgendwann programmieren.
Paxdiablo
2
Einverstanden. Ich habe diese Art von Funktionalität schon einmal benötigt und darauf zurückgegriffen, sie mit Visio vorzutäuschen. Benötigte es für die EU-Dokumentation. Auf jeden Fall war Code verwandt.
Joseph Ferris
6
SEHR dumm, dies als Off-Topic zu schließen. Ich habe auch ein Bedürfnis nach etwas gefunden. SO liebt es zu zensieren.
Boltimuss
1
Es tut mir leid, wenn meine Frage hier nicht zum Thema gehört. Ich verstehe den Grund warum. Vielen Dank an alle, die geantwortet haben, es war hilfreich. Zur Verdeutlichung benötigte ich ein Diagramm, um es in die Dokumentation des Projektbaums aufzunehmen. Screenshot schneidet es nicht, weil der gesamte Baum länger ist als auf einen Bildschirm passt.
Michael

Antworten:

92

Das Kopieren und Einfügen aus dem MS-DOS- treeBefehl funktioniert möglicherweise auch für Sie. Beispiele:

Baum

C:\Foobar>tree
C:.
├───FooScripts
├───barconfig
├───Baz
   ├───BadBaz
   └───Drop
...

Baum / F.

C:\Foobar>tree
C:.
├───FooScripts
    foo.sh
├───barconfig
    bar.xml
├───Baz
   ├───BadBaz
       badbaz.xml
   └───Drop
...

Baum / A.

C:\Foobar>tree /A
C:.
+---FooScripts
+---barconfig
+---Baz
¦   +---BadBaz
¦   \---Drop
...

Baum / F / A.

C:\Foobar>tree /A
C:.
+---FooScripts
¦    foo.sh
+---barconfig
¦    bar.xml
+---Baz
¦   +---BadBaz
¦   ¦    badbaz.xml
¦   \---Drop
...

Syntax [ Quelle ]

tree[ drive:] [ path] [ /F] [ /A]

drive:\path - Laufwerk und Verzeichnis mit Datenträger zur Anzeige der Verzeichnisstruktur, ohne Dateien aufzulisten.

/F - Schließen Sie alle Dateien ein, die in jedem Verzeichnis gespeichert sind.

/A- Ersetzen Sie Grafikzeichen, die zum Verknüpfen von Linien verwendet werden, durch Ext-Zeichen anstelle von Grafikzeichen. /awird mit Codepages verwendet, die keine Grafikzeichen unterstützen, und um Ausgaben an Drucker zu senden, die Grafikzeichen nicht richtig interpretieren.

svinto
quelle
1
Gute Idee, aber wenn es Dateien / Ordner mit Buchstaben mit Akzent gibt, werden diese im OEM-Zeichensatz und nicht im Ansi-Zeichensatz angezeigt. Wahrscheinlich kein Problem für die meisten (zumindest englischsprachigen) Benutzer. Gleiches gilt für halbgrafische Zeichen.
PhiLho
4
Linux hat auch einen "Baum" -Befehl wie diesen, den ich gerade nach dem Auschecken dieser Frage zum Stapelüberlauf entdeckt habe. Vielen Dank für den Hinweis auf den Namen, nach dem ich suchen sollte! "Baum -A" ist, wie man den Baum mit hübschen Zeichen erstellt; Ein einfacher "Baum" beschränkt sich nur auf ASCII.
Brandon Rhodes
1
schön, ich kannte diesen Befehl nicht einmal
MiniScalope
Vielen Dank an alle, die sie angesprochen haben. Ich halte dies für eine Antwort, denn das habe ich am Ende verwendet.
Michael
1
Oder speichern Sie es direkt in einer Datei: tree > file_structure.txtIch weiß, dass dies auf Unix-Systemen funktioniert. Ich weiß nicht, ob es auch unter Windows funktioniert.
Lucio Mollinedo
19

Graphviz - von der Webseite:

Die Graphviz-Layoutprogramme beschreiben Grafiken in einer einfachen Textsprache und erstellen Diagramme in verschiedenen nützlichen Formaten wie Bilder und SVG für Webseiten, Postscript für die Aufnahme in PDF oder andere Dokumente. oder in einem interaktiven Grafikbrowser anzeigen. (Graphviz unterstützt auch GXL, einen XML-Dialekt.)

Es ist das einfachste und produktivste Tool, das ich gefunden habe, um eine Vielzahl von Box-and-Line-Diagrammen zu erstellen. Ich habe und benutze Visio und OmniGraffle, aber es besteht immer die Versuchung, "nur noch eine Anpassung" vorzunehmen.

Es ist auch recht einfach, Code zu schreiben, um das von Graphiz verwendete "Punktedatei" -Format zu erzeugen, sodass die automatisierte Diagrammproduktion ebenfalls in Reichweite ist.

joel.neely
quelle
5

Wie versprochen, hier ist meine Kairoer Version. Ich habe es mit Lua geschrieben und lfs verwendet, um die Verzeichnisse zu durchsuchen. Ich liebe diese kleinen Herausforderungen, da sie es mir ermöglichen, APIs zu erkunden, die ich schon seit einiger Zeit ausgraben wollte ...
lfs und LuaCairo sind beide plattformübergreifend, daher sollte es auf anderen Systemen funktionieren (getestet auf Französisch WinXP Pro SP3).

Ich habe eine erste Version erstellt, in der Dateinamen gezeichnet wurden, als ich über den Baum ging. Vorteil: kein Speicheraufwand. Unannehmlichkeiten: Ich muss die Bildgröße im Voraus angeben, damit die Einträge wahrscheinlich abgeschnitten werden.

Also habe ich diese Version erstellt, indem ich zuerst den Verzeichnisbaum durchgesehen und in einer Lua-Tabelle gespeichert habe. Dann müssen Sie die Anzahl der Dateien kennen, die Leinwand (zumindest vertikal) passend erstellen und die Namen zeichnen.
Sie können problemlos zwischen PNG-Rendering und SVG-Rendering wechseln. Problem mit letzterem: Kairo generiert es auf niedriger Ebene und zeichnet die Buchstaben, anstatt die Textfunktion von SVG zu verwenden. Zumindest garantiert es eine genaue Wiedergabe auch auf Systemen ohne Schriftart. Aber die Dateien sind größer ... Kein wirkliches Problem, wenn Sie es danach komprimieren, um eine .svgz-Datei zu haben.
Oder es sollte nicht zu schwierig sein, die SVG direkt zu generieren. Ich habe Lua in der Vergangenheit verwendet, um SVG zu generieren.

-- LuaFileSystem <http://www.keplerproject.org/luafilesystem/>
require"lfs"
-- LuaCairo <http://www.dynaset.org/dogusanh/>
require"lcairo"
local CAIRO = cairo


local PI = math.pi
local TWO_PI = 2 * PI

--~ local dirToList = arg[1] or "C:/PrgCmdLine/Graphviz"
--~ local dirToList = arg[1] or "C:/PrgCmdLine/Tecgraf"
local dirToList = arg[1] or "C:/PrgCmdLine/tcc"
-- Ensure path ends with /
dirToList = string.gsub(dirToList, "([^/])$", "%1/")
print("Listing: " .. dirToList)
local fileNb = 0

--~ outputType = 'svg'
outputType = 'png'

-- dirToList must have a trailing slash
function ListDirectory(dirToList)
  local dirListing = {}
  for file in lfs.dir(dirToList) do
    if file ~= ".." and file ~= "." then
      local fileAttr = lfs.attributes(dirToList .. file)
      if fileAttr.mode == "directory" then
        dirListing[file] = ListDirectory(dirToList .. file .. '/')
      else
        dirListing[file] = ""
      end
      fileNb = fileNb + 1
    end
  end
  return dirListing
end

--dofile[[../Lua/DumpObject.lua]] -- My own dump routine
local dirListing = ListDirectory(dirToList)
--~ print("\n" .. DumpObject(dirListing))
print("Found " .. fileNb .. " files")

--~ os.exit()

-- Constants to change to adjust aspect
local initialOffsetX = 20
local offsetY = 50
local offsetIncrementX = 20
local offsetIncrementY = 12
local iconOffset = 10

local width = 800 -- Still arbitrary
local titleHeight = width/50
local height = offsetIncrementY * (fileNb + 1) + titleHeight
local outfile = "CairoDirTree." .. outputType

local ctxSurface
if outputType == 'svg' then
  ctxSurface = cairo.SvgSurface(outfile, width, height)
else
  ctxSurface = cairo.ImageSurface(CAIRO.FORMAT_RGB24, width, height)
end
local ctx = cairo.Context(ctxSurface)

-- Display a file name
-- file is the file name to display
-- offsetX is the indentation
function DisplayFile(file, bIsDir, offsetX)
  if bIsDir then
    ctx:save()
    ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_BOLD)
    ctx:set_source_rgb(0.5, 0.0, 0.7)
  end

  -- Display file name
  ctx:move_to(offsetX, offsetY)
  ctx:show_text(file)

  if bIsDir then
    ctx:new_sub_path() -- Position independent of latest move_to
    -- Draw arc with absolute coordinates
    ctx:arc(offsetX - iconOffset, offsetY - offsetIncrementY/3, offsetIncrementY/3, 0, TWO_PI)
    -- Violet disk
    ctx:set_source_rgb(0.7, 0.0, 0.7)
    ctx:fill()
    ctx:restore() -- Restore original settings
  end

  -- Increment line offset
  offsetY = offsetY + offsetIncrementY
end

-- Erase background (white)
ctx:set_source_rgb(1.0, 1.0, 1.0)
ctx:paint()

--~ ctx:set_line_width(0.01)

-- Draw in dark blue
ctx:set_source_rgb(0.0, 0.0, 0.3)
ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_BOLD)
ctx:set_font_size(titleHeight)
ctx:move_to(5, titleHeight)
-- Display title
ctx:show_text("Directory tree of " .. dirToList)

-- Select font for file names
ctx:select_font_face("Sans", CAIRO.FONT_SLANT_NORMAL, CAIRO.FONT_WEIGHT_NORMAL)
ctx:set_font_size(10)
offsetY = titleHeight * 2

-- Do the job
function DisplayDirectory(dirToList, offsetX)
  for k, v in pairs(dirToList) do
--~ print(k, v)
    if type(v) == "table" then
      -- Sub-directory
      DisplayFile(k, true, offsetX)
      DisplayDirectory(v, offsetX + offsetIncrementX)
    else
      DisplayFile(k, false, offsetX)
    end
  end
end

DisplayDirectory(dirListing, initialOffsetX)

if outputType == 'svg' then
    cairo.show_page(ctx)
else
  --cairo.surface_write_to_png(ctxSurface, outfile)
  ctxSurface:write_to_png(outfile)
end

ctx:destroy()
ctxSurface:destroy()

print("Found " .. fileNb .. " files")

Natürlich können Sie die Stile ändern. Ich habe die Verbindungslinien nicht gezeichnet, ich habe es nicht als notwendig angesehen. Ich könnte sie optional später hinzufügen.

PhiLho
quelle
3

Warum können Sie nicht einfach eine Dateistruktur im Windows-Dateisystem erstellen und diese mit Ihren gewünschten Namen füllen? Verwenden Sie dann einen Screen Grabber wie HyperSnap (oder das allgegenwärtige Alt-PrtScr), um einen Abschnitt des Explorer-Fensters zu erfassen.

Ich habe dies getan, als ich eine Internetanwendung mit zusammenklappbaren Abschnitten "vorführte". Ich musste nur Dateien erstellen, die meinen gewünschten Einträgen entsprachen.

HyperSnap gibt zumindest JPGs (wahrscheinlich andere, aber ich habe mich nie darum gekümmert, dies zu untersuchen).

Sie können auch die Symbole +/- aus dem Explorer auf dem Bildschirm erfassen und sie in MS Word Draw selbst verwenden, um Ihr Bild zu erstellen, aber ich habe MS Word Draw noch nie dazu gebracht, sich richtig zu verhalten.

paxdiablo
quelle
2

Der Rat für die Verwendung von Graphviz ist gut: Sie können die Punktdatei generieren und es wird die harte Arbeit des Messens von Zeichenfolgen, des Layouts usw. erledigen. Außerdem können die Diagramme in vielen Formaten ausgegeben werden, einschließlich Vektorformaten.

Ich habe in einer Mailingliste ein Perl-Programm gefunden, das genau das tut, aber ich kann es einfach nicht zurückfinden! Ich habe die Beispiel-Punktdatei kopiert und studiert, da ich nicht viel über diese deklarative Syntax weiß und etwas mehr lernen wollte.

Problem: Mit dem neuesten Graphviz habe ich Fehler (oder besser gesagt Warnungen, wenn das endgültige Diagramm erstellt wird), sowohl im Originaldiagramm als auch in dem von mir geschriebenen (von Hand). Einige Suchanfragen haben gezeigt, dass dieser Fehler in alten Versionen gefunden wurde und in neueren Versionen verschwunden ist. Sieht aus wie es zurück ist.

Ich gebe die Datei immer noch, vielleicht kann sie ein Ausgangspunkt für jemanden sein, oder vielleicht reicht sie für Ihre Bedürfnisse aus (natürlich müssen Sie sie noch generieren).

digraph tree
{
  rankdir=LR;

  DirTree [label="Directory Tree" shape=box]

  a_Foo_txt [shape=point]
  f_Foo_txt [label="Foo.txt", shape=none]
  a_Foo_txt -> f_Foo_txt

  a_Foo_Bar_html [shape=point]
  f_Foo_Bar_html [label="Foo Bar.html", shape=none]
  a_Foo_Bar_html -> f_Foo_Bar_html

  a_Bar_png [shape=point]
  f_Bar_png [label="Bar.png", shape=none]
  a_Bar_png -> f_Bar_png

  a_Some_Dir [shape=point]
  d_Some_Dir [label="Some Dir", shape=ellipse]
  a_Some_Dir -> d_Some_Dir

  a_VBE_C_reg [shape=point]
  f_VBE_C_reg [label="VBE_C.reg", shape=none]
  a_VBE_C_reg -> f_VBE_C_reg

  a_P_Folder [shape=point]
  d_P_Folder [label="P Folder", shape=ellipse]
  a_P_Folder -> d_P_Folder

  a_Processing_20081117_7z [shape=point]
  f_Processing_20081117_7z [label="Processing-20081117.7z", shape=none]
  a_Processing_20081117_7z -> f_Processing_20081117_7z

  a_UsefulBits_lua [shape=point]
  f_UsefulBits_lua [label="UsefulBits.lua", shape=none]
  a_UsefulBits_lua -> f_UsefulBits_lua

  a_Graphviz [shape=point]
  d_Graphviz [label="Graphviz", shape=ellipse]
  a_Graphviz -> d_Graphviz

  a_Tree_dot [shape=point]
  f_Tree_dot [label="Tree.dot", shape=none]
  a_Tree_dot -> f_Tree_dot

  {
    rank=same;
    DirTree -> a_Foo_txt -> a_Foo_Bar_html -> a_Bar_png -> a_Some_Dir -> a_Graphviz [arrowhead=none]
  }
  {
    rank=same;
    d_Some_Dir -> a_VBE_C_reg -> a_P_Folder -> a_UsefulBits_lua [arrowhead=none]
  }
  {
    rank=same;
    d_P_Folder -> a_Processing_20081117_7z [arrowhead=none]
  }
  {
    rank=same;
    d_Graphviz -> a_Tree_dot [arrowhead=none]
  }
}

> dot -Tpng Tree.dot -o Tree.png
Error: lost DirTree a_Foo_txt edge
Error: lost a_Foo_txt a_Foo_Bar_html edge
Error: lost a_Foo_Bar_html a_Bar_png edge
Error: lost a_Bar_png a_Some_Dir edge
Error: lost a_Some_Dir a_Graphviz edge
Error: lost d_Some_Dir a_VBE_C_reg edge
Error: lost a_VBE_C_reg a_P_Folder edge
Error: lost a_P_Folder a_UsefulBits_lua edge
Error: lost d_P_Folder a_Processing_20081117_7z edge
Error: lost d_Graphviz a_Tree_dot edge

Ich werde eine andere Richtung ausprobieren, indem ich Kairo verwende, das auch eine Reihe von Formaten exportieren kann. Es ist mehr Arbeit (Berechnen von Positionen / Offsets), aber die Struktur ist einfach und sollte nicht zu schwierig sein.

PhiLho
quelle
1
Steve DeRose hat eine Perlscript-Dateistruktur -> Punktdatei
claj