bash 用什么工具画文件树图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/347551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What tool to use to draw file tree diagram
提问by Michael
Given a file tree - a directory with directories in it etc, how would you write a script to create a diagram of the file-tree as a graphic file that I can embed in a word processor document. I prefer vector (SVG, EPS, EMF...) files. The tool must run on Windows, but preferably cross-platform. The tool may be commercial but preferably free.
给定一个文件树 - 一个包含目录等的目录,您将如何编写脚本来创建文件树的图表作为我可以嵌入到文字处理器文档中的图形文件。我更喜欢矢量(SVG、EPS、EMF...)文件。该工具必须在 Windows 上运行,但最好是跨平台的。该工具可以是商业的,但最好是免费的。
Update 2012-02-20. The question was related to a documentation sub project. I had to explan where files (in particular resources and configuration files) reside. I ended up with using dos tree command. I both screen grabbed the result (for short folders) AND for longer folders I redirected to a text file, which I then edited. For example if a subfolder contained 20 similarly typed files that individually were not important to the point I was making, I left just two and replaced the rest with one ... line. I then printed out the file to console again and screen grabbed it. Before screen grabbing I had to modify foreground color to black and background color to white, to look better and save ink in a document should that be printed.
更新 2012-02-20。该问题与文档子项目有关。我必须解释文件(特别是资源和配置文件)所在的位置。我最终使用了 dos tree 命令。我在屏幕上都抓取了结果(对于短文件夹),对于较长的文件夹,我重定向到一个文本文件,然后我对其进行了编辑。例如,如果一个子文件夹包含 20 个类似类型的文件,这些文件对我正在制作的点来说并不重要,我只留下两个并用一个 ... 行替换其余的。然后我再次将文件打印到控制台并通过屏幕抓取它。在屏幕抓取之前,我必须将前景色修改为黑色,将背景色修改为白色,以便在打印时看起来更好并节省文档中的墨水。
It is very surprising that there is no better tool for it. If I had time, I'd write a Visio Extension or may be some command line that produces SVG. SVG being HTML5 substandard, would even allow painless inclusion into online documentation.
非常令人惊讶的是,没有更好的工具可以用于它。如果我有时间,我会写一个 Visio 扩展,或者可能是一些生成 SVG 的命令行。SVG 不符合 HTML5 标准,甚至可以轻松地将其包含到在线文档中。
Update 2017-10-17. I am sorry that this question was removed as not belonging to SO. So I have re-worded it. I need a script - not a WYSIWYG tool. So any scripting language or library is ok. So it is a code - writing question, and I believe belongs to SO.
更新 2017-10-17。我很抱歉这个问题被删除,因为它不属于 SO。所以我已经重新措辞了。我需要一个脚本 - 而不是 WYSIWYG 工具。所以任何脚本语言或库都可以。所以这是一个代码编写问题,我相信属于 SO。
回答by svinto
Copying and pasting from the MS-DOS tree
command might also work for you. Examples:
从 MS-DOStree
命令复制和粘贴也可能对您有用。例子:
tree
树
C:\Foobar>tree
C:.
├───FooScripts
├───barconfig
├───Baz
│ ├───BadBaz
│ └───Drop
...
tree /F
树 /F
C:\Foobar>tree
C:.
├───FooScripts
│ foo.sh
├───barconfig
│ bar.xml
├───Baz
│ ├───BadBaz
│ │ badbaz.xml
│ └───Drop
...
tree /A
树 /A
C:\Foobar>tree /A
C:.
+---FooScripts
+---barconfig
+---Baz
| +---BadBaz
| \---Drop
...
tree /F /A
树 /F /A
C:\Foobar>tree /A
C:.
+---FooScripts
| foo.sh
+---barconfig
| bar.xml
+---Baz
| +---BadBaz
| | badbaz.xml
| \---Drop
...
Syntax [source]
语法[来源]
tree
[drive:
][path
] [/F
] [/A
]
tree
[ drive:
][ path
] [ /F
] [ /A
]
drive:\path
— Drive and directory containing disk for display of directory structure, without listing files.
/F
— Include all files living in every directory.
/A
— Replace graphic characters used for linking lines with ext characters , instead of graphic characters./a
is used with code pages that do not support graphic characters and to send output to printers that do not properly interpret graphic characters.
drive:\path
— 包含用于显示目录结构的磁盘的驱动器和目录,不列出文件。
/F
— 包含每个目录中的所有文件。
/A
— 将用于链接行的图形字符替换为 ext 字符,而不是图形字符。/a
用于不支持图形字符的代码页,并将输出发送到不能正确解释图形字符的打印机。
回答by joel.neely
Graphviz- from the web page:
Graphviz- 来自网页:
The Graphviz layout programs take descriptions of graphs in a simple text language, and make diagrams in several useful formats such as images and SVG for web pages, Postscript for inclusion in PDF or other documents; or display in an interactive graph browser. (Graphviz also supports GXL, an XML dialect.)
Graphviz 布局程序以简单的文本语言对图形进行描述,并以多种有用的格式制作图表,例如用于网页的图像和 SVG,用于包含在 PDF 或其他文档中的 Postscript;或显示在交互式图形浏览器中。(Graphviz 还支持 GXL,一种 XML 方言。)
It's the simplest and most productive tool I've found to create a variety of boxes-and-lines diagrams. I have and use Visio and OmniGraffle, but there's always the temptation to make "just one more adjustment".
这是我发现的最简单、最高效的工具,可用于创建各种框线图。我拥有并使用 Visio 和 OmniGraffle,但总是有“再做一次调整”的诱惑。
It's also quite easy to write code to produce the "dot file" format that Graphiz consumes, so automated diagram production is also nicely within reach.
编写代码来生成 Graphiz 使用的“点文件”格式也很容易,因此自动化图表生成也很容易实现。
回答by PhiLho
As promised, here is my Cairo version. I scripted it with Lua, using lfs to walk the directories. I love these little challenges, as they allow me to explore APIs I wanted to dig for quite some time...
lfs and LuaCairo are both cross-platform, so it should work on other systems (tested on French WinXP Pro SP3).
正如所承诺的,这是我的开罗版本。我用 Lua 编写了它,使用 lfs 来遍历目录。我喜欢这些小挑战,因为它们让我能够探索我想挖掘的 API 很长一段时间......
lfs 和 LuaCairo 都是跨平台的,所以它应该适用于其他系统(在法国 WinXP Pro SP3 上测试)。
I made a first version drawing file names as I walked the tree. Advantage: no memory overhead. Inconvenience: I have to specify the image size beforehand, so listings are likely to be cut off.
我在走树时制作了第一个版本的绘图文件名。优点:没有内存开销。不便:我必须事先指定图像大小,因此列表可能会被切断。
So I made this version, first walking the directory tree, storing it in a Lua table. Then, knowing the number of files, creating the canvas to fit (at least vertically) and drawing the names.
You can easily switch between PNG rendering and SVG one. Problem with the latter: Cairo generates it at low level, drawing the letters instead of using SVG's text capability. Well, at least, it guarantees accurate rending even on systems without the font. But the files are bigger... Not really a problem if you compress it after, to have a .svgz file.
Or it shouldn't be too hard to generate the SVG directly, I used Lua to generate SVG in the past.
所以我做了这个版本,首先遍历目录树,将它存储在一个 Lua 表中。然后,知道文件的数量,创建适合(至少垂直)的画布并绘制名称。
您可以轻松地在 PNG 渲染和 SVG 渲染之间切换。后者的问题:Cairo 在低级别生成它,绘制字母而不是使用 SVG 的文本功能。好吧,至少,即使在没有字体的系统上,它也能保证准确的渲染。但是文件更大......如果你压缩它之后有一个.svgz文件并不是真正的问题。
或者直接生成SVG应该不会太难,我以前用Lua生成SVG。
-- 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")
Of course, you can change the styles. I didn't draw the connection lines, I didn't saw it as necessary. I might add them optionally later.
当然,您可以更改样式。我没有画连接线,我没有看到它有必要。稍后我可能会选择添加它们。
回答by paxdiablo
Why could you not just make a file structure on the Windows file system and populate it with your desired names, then use a screen grabber like HyperSnap (or the ubiquitous Alt-PrtScr) to capture a section of the Explorer window.
为什么不直接在 Windows 文件系统上创建一个文件结构并用您想要的名称填充它,然后使用像 HyperSnap(或无处不在的 Alt-PrtScr)这样的屏幕抓取器来捕获资源管理器窗口的一部分。
I did this when 'demoing' an internet application which would have collapsible sections, I just had to create files that looked like my desired entries.
我在“演示”一个具有可折叠部分的互联网应用程序时这样做了,我只需要创建看起来像我想要的条目的文件。
HyperSnap gives JPGs at least (probably others but I've never bothered to investigate).
HyperSnap 至少提供 JPG(可能是其他的,但我从来没有费心研究过)。
Or you could screen capture the icons +/- from Explorer and use them within MS Word Draw itself to do your picture, but I've never been able to get MS Word Draw to behave itself properly.
或者您可以从资源管理器屏幕捕获图标 +/- 并在 MS Word Draw 本身中使用它们来制作图片,但我从来没有让 MS Word Draw 正常运行。
回答by PhiLho
The advice to use Graphviz is good: you can generate the dot file and it will do the hard work of measuring strings, doing the layout, etc. Plus it can output the graphs in lot of formats, including vector ones.
使用 Graphviz 的建议很好:您可以生成点文件,它会完成测量字符串、布局等的繁重工作。此外,它还可以输出多种格式的图形,包括矢量格式。
I found a Perl program doing precisely that, in a mailing list, but I just can't find it back! I copied the sample dot file and studied it, since I don't know much of this declarative syntax and I wanted to learn a bit more.
我在邮件列表中发现了一个 Perl 程序正是这样做的,但我找不到它!我复制了示例点文件并研究了它,因为我对这种声明式语法了解不多,我想了解更多。
Problem: with latest Graphviz, I have errors (or rather, warnings, as the final diagram is generated), both in the original graph and the one I wrote (by hand). Some searches shown this error was found in old versions and disappeared in more recent versions. Looks like it is back.
问题:使用最新的 Graphviz,我在原始图表和我(手工)编写的图表中都有错误(或者更确切地说,是警告,因为生成了最终图表)。一些搜索显示此错误是在旧版本中发现的,并在较新的版本中消失。看起来它回来了。
I still give the file, maybe it can be a starting point for somebody, or maybe it is enough for your needs (of course, you still have to generate it).
我还是把文件给了,也许它可以作为某人的起点,或者它足以满足您的需求(当然,您仍然需要生成它)。
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
I will try another direction, using Cairo, which is also able to export a number of formats. It is more work (computing positions/offsets) but the structure is simple, shouldn't be too hard.
我将尝试另一个方向,使用 Cairo,它也能够导出多种格式。这是更多的工作(计算位置/偏移量),但结构很简单,应该不会太难。