bash - update - Qué herramienta usar para dibujar el diagrama del árbol de archivos
qué comando shell acepta la entrada del teclado del usuario (5)
Dado un árbol de archivos, un directorio con directorios en él, etc., ¿cómo escribirías un guión para crear un diagrama del árbol de archivos como un archivo gráfico que puedo incrustar en un documento de procesador de textos? Prefiero archivos vectoriales (SVG, EPS, EMF ...). La herramienta debe ejecutarse en Windows, pero preferiblemente multiplataforma. La herramienta puede ser comercial, pero preferiblemente gratuita.
Actualización 2012-02-20. La pregunta estaba relacionada con un subproyecto de documentación. Tuve que explicar dónde residen los archivos (en particular los recursos y los archivos de configuración). Terminé usando el comando dos árboles. Las dos pantallas obtuve el resultado (para las carpetas cortas) Y para las carpetas más largas redirigí a un archivo de texto, que luego edité. Por ejemplo, si una subcarpeta contenía 20 archivos tipados de manera similar que individualmente no eran importantes para el punto que estaba haciendo, dejé solo dos y reemplacé el resto con una ... línea. Luego imprimí el archivo en la consola nuevamente y la pantalla lo agarró. Antes de capturar la pantalla, tuve que modificar el color de primer plano a negro y el de fondo a blanco, para ver mejor y guardar tinta en un documento en caso de que se imprimiera.
Es muy sorprendente que no haya una mejor herramienta para ello. Si tuviera tiempo, escribiría una extensión de Visio o podría ser una línea de comando que produce SVG. SVG es HTML5 de calidad inferior, incluso permitiría la inclusión indolora en la documentación en línea.
Actualización 2017-10-17. Lamento que esta pregunta se haya eliminado porque no pertenece a SO. Así que lo he vuelto a redactar. Necesito un script, no un WYSIWYG también. Entonces, cualquier lenguaje o librería de scripting está bien. Entonces es una pregunta de escritura de código, y creo que pertenece a SO.
¿Por qué no podría simplemente hacer una estructura de archivos en el sistema de archivos de Windows y llenarla con sus nombres deseados, luego usar un capturador de pantalla como HyperSnap (o el Alt-PrtScr omnipresente) para capturar una sección de la ventana del Explorador.
Lo hice cuando ''demoing'' una aplicación de Internet que tendría secciones plegables, solo tuve que crear archivos que se parecían a mis entradas deseadas.
HyperSnap da JPG al menos (probablemente otros pero nunca me he molestado en investigar).
O puede capturar los iconos +/- de la pantalla del Explorador y usarlos en MS Word Draw para hacer su fotografía, pero nunca pude lograr que MS Word Draw se comporte correctamente.
Como prometí, aquí está mi versión de El Cairo. Lo escribí con Lua, usando lfs para recorrer los directorios. Me encantan estos pequeños desafíos, ya que me permiten explorar las API que quería excavar durante bastante tiempo ...
lfs y LuaCairo son multiplataforma, por lo que debería funcionar en otros sistemas (probado en francés WinXP Pro SP3).
Hice una primera versión dibujando nombres de archivos mientras caminaba por el árbol. Ventaja: sin gastos generales de memoria. Inconveniencia: tengo que especificar el tamaño de la imagen de antemano, por lo que es probable que los listados se corten.
Así que hice esta versión, primero caminando por el árbol de directorios, almacenándolo en una tabla de Lua. Luego, conocer la cantidad de archivos, crear el lienzo para que quepa (al menos verticalmente) y dibujar los nombres.
Puede cambiar fácilmente entre la representación PNG y SVG uno. Problema con este último: Cairo lo genera a bajo nivel, dibujando las letras en lugar de usar la capacidad de texto de SVG. Bueno, al menos, garantiza un desgarro preciso incluso en sistemas sin la fuente. Pero los archivos son más grandes ... No es realmente un problema si lo comprimes después, para tener un archivo .svgz.
O no debería ser demasiado difícil generar el SVG directamente, utilicé Lua para generar SVG en el pasado.
-- 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")
Por supuesto, puedes cambiar los estilos. No dibujé las líneas de conexión, no lo vi como necesario. Podría agregarlos opcionalmente más tarde.
Los consejos para usar Graphviz son buenos: puede generar el archivo de puntos y hará el trabajo duro de medir cadenas, hacer el diseño, etc. Además, puede mostrar los gráficos en muchos formatos, incluidos los vectores.
Encontré un programa Perl haciendo precisamente eso, en una lista de correo, ¡pero no puedo encontrarlo! Copié el archivo de puntos de muestra y lo estudié, ya que no sé mucho de esta sintaxis declarativa y quería aprender un poco más.
Problema: con la última versión de Graphviz, tengo errores (o mejor dicho, advertencias, a medida que se genera el diagrama final), tanto en el gráfico original como en el que escribí (a mano). Algunas búsquedas muestran que este error se encontró en versiones antiguas y desapareció en versiones más recientes. Parece que está de vuelta.
Todavía doy el archivo, tal vez puede ser un punto de partida para alguien, o tal vez es suficiente para sus necesidades (por supuesto, todavía tiene que generarlo).
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
Intentaré otra dirección, usando Cairo, que también puede exportar varios formatos. Es más trabajo (calcular posiciones / compensaciones) pero la estructura es simple, no debería ser demasiado difícil.
Graphviz - desde la página web:
Los programas de diseño de Graphviz toman descripciones de gráficos en un lenguaje de texto simple y hacen diagramas en varios formatos útiles, como imágenes y SVG para páginas web, Postscript para su inclusión en PDF u otros documentos; o mostrar en un navegador gráfico interactivo. (Graphviz también es compatible con GXL, un dialecto XML).
Es la herramienta más simple y productiva que he encontrado para crear una variedad de diagramas de cajas y líneas. Tengo y uso Visio y OmniGraffle, pero siempre existe la tentación de hacer "solo un ajuste más".
También es bastante fácil escribir código para producir el formato de "archivo de puntos" que Graphiz consume, por lo que la producción automática de diagramas también está al alcance.
Copiar y pegar desde el comando de tree
MS-DOS también podría funcionar para usted. Ejemplos:
árbol
C:/Foobar>tree
C:.
├───FooScripts
├───barconfig
├───Baz
│ ├───BadBaz
│ └───Drop
...
árbol / F
C:/Foobar>tree
C:.
├───FooScripts
│ foo.sh
├───barconfig
│ bar.xml
├───Baz
│ ├───BadBaz
│ │ badbaz.xml
│ └───Drop
...
árbol / A
C:/Foobar>tree /A
C:.
+---FooScripts
+---barconfig
+---Baz
¦ +---BadBaz
¦ /---Drop
...
árbol / F / A
C:/Foobar>tree /A
C:.
+---FooScripts
¦ foo.sh
+---barconfig
¦ bar.xml
+---Baz
¦ +---BadBaz
¦ ¦ badbaz.xml
¦ /---Drop
...
Sintaxis [ source ]
tree
[ drive:
] [ path
] [ /F
] [ /A
]
drive:/path
- Unidad y directorio que contiene el disco para mostrar la estructura del directorio, sin listados de archivos.
/F
- Incluye todos los archivos que viven en cada directorio.
/A
- Reemplaza los caracteres gráficos utilizados para unir líneas con caracteres ext, en lugar de caracteres gráficos./a
se usa con páginas de códigos que no admiten caracteres gráficos y para enviar resultados a impresoras que no interpretan correctamente los caracteres gráficos.