404

I want a Linux command to print directory & file structures in the form of a tree, possibly with Unicode icons before each file, and some hint for the best syntax to include the output in a Markdown document, without spaces between lines.

Example:

.
├── _config.yml
├── _drafts
│   ├── begin-with-the-crazy-ideas. Textile
│   └── on-simplicity-in-technology. Markdown
├── _includes
│   ├── footer.html
│   └── header.html
├── _layouts
│   ├── default.html
│   └── post.html
├── _posts
│   ├── 2007-10-29-why-every-programmer-should-play-nethack.textile
│   └── 2009-04-26-barcamp-boston-4-roundup.textile
├── _data
│   └── members.yml
├── _site
└── index.html
Matt Rowles
  • 7,721
  • 18
  • 55
  • 88
  • 5
    This has been discussed on Meta at [Is there a good way to represent file structure in a question/answer?](http://meta.stackexchange.com/questions/147467/is-there-a-good-way-to-represent-file-structure-in-a-question-answer) – Dan Dascalescu Oct 02 '14 at 17:06
  • 1
    since you mentioned jekyll specifically, this no-fluff [example](http://atstp.github.io/wasabi_and_jekyll/) and its [source](https://github.com/atstp/wasabi_and_jekyll/) might fit the bill – user3276552 Aug 06 '15 at 20:07
  • 5
    I am using https://tree.nathanfriend.io – HemanthJabalpuri Jan 10 '21 at 03:38

12 Answers12

447

I followed an example in another repository and wrapped the directory structure within a pair of triple backticks (```):

```
project
│   README.md
│   file001.txt    
│
└───folder1
│   │   file011.txt
│   │   file012.txt
│   │
│   └───subfolder1
│       │   file111.txt
│       │   file112.txt
│       │   ...
│   
└───folder2
    │   file021.txt
    │   file022.txt
```
William
  • 352
  • 4
  • 16
user799188
  • 13,965
  • 5
  • 35
  • 37
  • 5
    Stack Overflow does not support the newer triple-backtick syntax; it interprets them as single backticks. Single backticks mark code as inline text, only within a single line; that’s why your example has white stripes between each line. For a compatible way to mark up multi-line code, indent the text by four spaces. – Rory O'Kane Apr 09 '15 at 20:54
  • 6
    While SO doesn't support the triple-backtick, most other MD implementations do (like Github/BitBucket) and this was the only way I could get a tree working that had inline comments as to what each entry was. So.. +1 from here! – Scott Byers Apr 18 '17 at 20:39
  • 1
    Thumbs up for this answer. Triple backticks markdown works for me on Wordpress too. – Binita Bharati Jan 31 '19 at 05:54
  • 4
    Triple-backtick support appears to work on SO now. – StriplingWarrior Jun 15 '20 at 19:59
  • 3
    Do you copy-paste the unicode `└` symbol, or is there a way to write them in ascii? – R.Falque Mar 16 '22 at 02:57
  • @R.Falque CTRL+Shift+`u` then input the [unicode](https://unicode-table.com/en/), in this case 2514. But I think this is a feature of gnome-based DEs? – Seriously Jul 25 '22 at 12:19
  • Is there any cool highlighting style to which such a triple-backtick box should be set? – Seriously Jul 25 '22 at 12:20
  • 2 newer options include (1). **Vim** and [**NERDTree**](https://github.com/preservim/nerdtree) and (2). [**exa**](https://github.com/ogham/exa). An alternative to `ls` with a built-in tree function. It features icons and coloured output. – ssent1 Aug 15 '23 at 20:22
216

If you are concerned about Unicode characters you can use ASCII to build the structures, so your example structure becomes

.
+-- _config.yml
+-- _drafts
|   +-- begin-with-the-crazy-ideas.textile
|   +-- on-simplicity-in-technology.markdown
+-- _includes
|   +-- footer.html
|   +-- header.html
+-- _layouts
|   +-- default.html
|   +-- post.html
+-- _posts
|   +-- 2007-10-29-why-every-programmer-should-play-nethack.textile
|   +-- 2009-04-26-barcamp-boston-4-roundup.textile
+-- _data
|   +-- members.yml
+-- _site
+-- index.html

Which is similar to the format tree uses if you select ANSI output.

Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
RobertKenny
  • 3,556
  • 2
  • 19
  • 17
  • 1
    Thanks for this. Should there be any concerns about using the Unicode characters though? Such as known issues with older browsers, Markdown rendering incorrectly etc – Matt Rowles Oct 31 '13 at 22:22
  • 2
    There shouldn't be any issue with Markdown, it is going to be on your Jekyll templates and users web browsers. – RobertKenny Nov 01 '13 at 09:31
  • 1
    Another advantage of this choice is smaller diffs compared to other choices that use different symbols for cosmetic reasons only (like the output from `tree`). – villasv Aug 16 '18 at 16:56
  • 3
    When using this anwser the tree is just renderd as a few text lines. Tested in VSCode and VisualStudio with md plugin. Also on GitHub this is not working – Danny Nov 22 '18 at 10:05
166

If you're using VS Code, this is an awesome extension for generating file trees.

Added directly to markdown...

quakehunter
 ┣ client
 ┣ node_modules
 ┣ server
 ┃ ┗ index.js
 ┣ .gitignore
 ┣ package-lock.json
 ┗ package.json
ashraful16
  • 2,742
  • 3
  • 11
  • 32
Will Ward
  • 1,886
  • 1
  • 10
  • 11
55

You can use tree to generate something very similar to your example. Once you have the output, you can wrap it in a <pre> tag to preserve the plain text formatting.

Cameron Spickert
  • 5,190
  • 1
  • 27
  • 34
  • Cool, this looks helpful thanks! But what about for theoretical file structures? If this is the only solution at the moment, I guess I might just have to copy and paste the characters I need. Cheers again. – Matt Rowles Oct 31 '13 at 05:36
  • I like this solution. Look neat in Markdown – Anh Tuan May 15 '18 at 07:52
  • Thanks, this is what I was looking for after using file-tree-generator. – Himanshu Mar 18 '22 at 16:02
52

As already recommended, you can use tree. But for using it together with restructured text some additional parameters were required.

The standard tree output will not be printed if your're using pandoc to produce pdf.

tree --dirsfirst --charset=ascii /path/to/directory will produce a nice ASCII tree that can be integrated into your document like this:

.. code::
.
|-- ContentStore
|   |-- de-DE
|   |   |-- art.mshc
|   |   |-- artnoloc.mshc
|   |   |-- clientserver.mshc
|   |   |-- noarm.mshc
|   |   |-- resources.mshc
|   |   `-- windowsclient.mshc
|   `-- en-US
|       |-- art.mshc
|       |-- artnoloc.mshc
|       |-- clientserver.mshc
|       |-- noarm.mshc
|       |-- resources.mshc
|       `-- windowsclient.mshc
`-- IndexStore
    |-- de-DE
    |   |-- art.mshi
    |   |-- artnoloc.mshi
    |   |-- clientserver.mshi
    |   |-- noarm.mshi
    |   |-- resources.mshi
    |   `-- windowsclient.mshi
    `-- en-US
        |-- art.mshi
        |-- artnoloc.mshi
        |-- clientserver.mshi
        |-- noarm.mshi
        |-- resources.mshi
        `-- windowsclient.mshi
aronadaal
  • 9,083
  • 1
  • 19
  • 33
26

I made a node module to automate this task: mddir

Usage

node mddir "../relative/path/"

To install: npm install mddir -g

To generate markdown for current directory: mddir

To generate for any absolute path: mddir /absolute/path

To generate for a relative path: mddir ~/Documents/whatever.

The md file gets generated in your working directory.

Currently ignores node_modules, and .git folders.

Troubleshooting

If you receive the error 'node\r: No such file or directory', the issue is that your operating system uses different line endings and mddir can't parse them without you explicitly setting the line ending style to Unix. This usually affects Windows, but also some versions of Linux. Setting line endings to Unix style has to be performed within the mddir npm global bin folder.

Line endings fix

Get npm bin folder path with:

npm config get prefix

Cd into that folder

brew install dos2unix

dos2unix lib/node_modules/mddir/src/mddir.js

This converts line endings to Unix instead of Dos

Then run as normal with: node mddir "../relative/path/".

Example generated markdown file structure 'directoryList.md'

    |-- .bowerrc
    |-- .jshintrc
    |-- .jshintrc2
    |-- Gruntfile.js
    |-- README.md
    |-- bower.json
    |-- karma.conf.js
    |-- package.json
    |-- app
        |-- app.js
        |-- db.js
        |-- directoryList.md
        |-- index.html
        |-- mddir.js
        |-- routing.js
        |-- server.js
        |-- _api
            |-- api.groups.js
            |-- api.posts.js
            |-- api.users.js
            |-- api.widgets.js
        |-- _components
            |-- directives
                |-- directives.module.js
                |-- vendor
                    |-- directive.draganddrop.js
            |-- helpers
                |-- helpers.module.js
                |-- proprietary
                    |-- factory.actionDispatcher.js
            |-- services
                |-- services.cardTemplates.js
                |-- services.cards.js
                |-- services.groups.js
                |-- services.posts.js
                |-- services.users.js
                |-- services.widgets.js
        |-- _mocks
            |-- mocks.groups.js
            |-- mocks.posts.js
            |-- mocks.users.js
            |-- mocks.widgets.js
John Byrne
  • 569
  • 5
  • 6
  • 1
    Sadly, I tried this, and it doesn't work on my Windows 10 machine, and it seems that the project has been abandoned. – Rich Hopkins Jul 29 '17 at 19:59
  • 1
    Hi, thanks for trying out the library. I've been busy on other projects and can't replicate but have found a possible fix. Get npm bin folder path with: 'npm config get prefix'. Cd into that folder, then run 'brew install dos2unix', run 'dos2unix lib/node_modules/mddir/src/mddir.js'. This converts line endings to Unix instead of Dos. Then run as normal with: node mddir "../relative/path/". – John Byrne Oct 28 '17 at 03:47
  • Worked on my Windows 10 machine, neat little utility - thanks! – John Kattenhorn Apr 05 '20 at 19:19
15

If you're using Atom editor, you can accomplish this by the ascii-tree package.

You can write the following tree:

root
+-- dir1
    +--file1
+-- dir2
    +-- file2

and convert it to the following by selecting it and pressing ctrl-alt-t:

root
├── dir1
│   └── file1
└── dir2
    └── file2
Ramtin Soltani
  • 2,650
  • 3
  • 24
  • 45
9

I scripted this for my Dropbox file list.

sed is used for removing full paths of symlinked file/folder path coming after ->

Unfortunately, tabs are lost. Using zsh I am able to preserve tabs.

!/usr/bin/env bash

#!/usr/bin/env zsh

F1='index-2.md' #With hyperlinks
F2='index.md'

if [ -e $F1 ];then
    rm $F1
fi

if [ -e $F2 ];then
    rm $F2
fi

DATA=`tree --dirsfirst -t -Rl --noreport | \
    sed 's/->.*$//g'`             # Remove symlink adress and ->

echo -e '```\n' ${DATA} '\n```' > $F1  # Markdown needs triple back ticks for <pre>

# With the power of piping, creating HTML tree than pipe it
# to html2markdown program, creates cool markdown file with hyperlinks.

DATA=`tree --dirsfirst -t -Rl --noreport -H http://guneysu.pancakeapps.com`
echo $DATA | \
    sed 's/\r\r/\n/g' | \
    html2markdown | \
    sed '/^\s*$/d' | \
    sed 's/\# Directory Tree//g' | \
        > $F2

The outputs like this:

```
 .
├── 2013 
│   └── index.markdown
├── 2014 
│   └── index.markdown
├── 2015 
│   └── index.markdown
├── _posts 
│   └── 2014-12-27-2014-yili-degerlendirmesi.markdown
├── _stash 
└── update.sh 
```

[BASE_URL/](BASE_URL/)
├── [2013](BASE_URL/2013/)
│   └── [index.markdown](BASE_URL/2013/index.markdown)
├── [2014](BASE_URL/2014/)
│   └── [index.markdown](BASE_URL/2014/index.markdown)
├── [2015](BASE_URL/2015/)
│   └── [index.markdown](BASE_URL/2015/index.markdown)
├── [_posts](BASE_URL/_posts/)
│   └── [2014-12-27-2014-yili-degerlendirmesi.markdown](_posts/2014-12-27-2014-yili-degerlendirmesi.markdown)
├── [_stash](BASE_URL/_stash/)
├── [index-2.md](BASE_URL/index-2.md)
└── [update.sh](BASE_URL/update.sh)
* * *
tree v1.6.0 © 1996 - 2011 by Steve Baker and Thomas Moore
HTML output hacked and copyleft © 1998 by Francesc Rocher
Charsets / OS/2 support © 2001 by Kyosuke Tokoro
guneysus
  • 6,203
  • 2
  • 45
  • 47
7

I'd suggest using wasabi then you can either use the markdown-ish feel like this

root/ # entry comments can be inline after a '#'
      # or on their own line, also after a '#'

  readme.md # a child of, 'root/', it's indented
            # under its parent.

  usage.md  # indented syntax is nice for small projects
            # and short comments.

  src/          # directories MUST be identified with a '/'
    fileOne.txt # files don't need any notation
    fileTwo*    # '*' can identify executables
    fileThree@  # '@' can identify symlinks

and throw that exact syntax at the js library for this

wasabi example

user3276552
  • 1,074
  • 12
  • 15
6

Under OSX, using reveal.js, I have got rendering issue if I just user tree and then copy/paste the output: strange symbols appear.

I have found 2 possible solutions.

1) Use charset ascii and simply copy/paste the output in the markdown file

tree -L 1 --charset=ascii

2) Use directly HTML and unicode in the markdown file

<pre>
.
&#8866; README.md
&#8866; docs
&#8866; e2e
&#8866; karma.conf.js
&#8866; node_modules
&#8866; package.json
&#8866; protractor.conf.js
&#8866; src
&#8866; tsconfig.json
&#8985; tslint.json
</pre>

Hope it helps.

1

If you wish to generate it dynamically I recommend using Frontend-md. It is simple to use.

Exil
  • 311
  • 2
  • 11
  • 26
Bruno Wego
  • 2,099
  • 3
  • 21
  • 38
1

There is an NPM module for this:

npm dree

It allows you to have a representation of a directory tree as a string or an object. Using it with the command line will allow you to save the representation in a txt file.

Example:

$ npm dree parse myDirectory --dest ./generated --name tree
EuberDeveloper
  • 874
  • 1
  • 14
  • 38