3

I would like to print out in terminal tree like one below:

$ tree -a
.
└── .git
    ├── branches
    ├── config
    ├── description
    ├── HEAD
    ├── hooks
    │   ├── applypatch-msg.sample
    │   ├── commit-msg.sample
    │   ├── fsmonitor-watchman.sample
    │   ├── post-update.sample
    │   ├── pre-applypatch.sample
    │   ├── pre-commit.sample
    │   ├── prepare-commit-msg.sample
    │   ├── pre-push.sample
    │   ├── pre-rebase.sample
    │   ├── pre-receive.sample
    │   └── update.sample
    ├── info
    │   └── exclude
    ├── objects
    │   ├── info
    │   └── pack
    └── refs
        ├── heads
        └── tags

With graphically presented content of all files ie it should like respectively?

.
└── .git
    ├── branches
    ├── config
    |
    |   [core]
    |        repositoryformatversion = 0
    |        filemode = true
    |        bare = false
    |        logallrefupdates = true
    |
    ├── description
    |
    |   Unnamed repository; edit this file 'description' to name the repository.
    |
    ├── HEAD
    |
    |   ref: refs/heads/master
    |

Is there an easy way to reach that?

0

1 Answer 1

3

I'm not aware of an easy way to do that, but I wrote a script that does something similar. Instead of a fancy tree listing like tree does, I made it flat, like find.

Output (in an empty git repo like your example):

.git/
.git/branches/
.git/config
==> start .git/config <==
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
==> end .git/config <==

.git/description
==> start .git/description <==
Unnamed repository; edit this file 'description' to name the repository.
==> end .git/description <==

.git/HEAD
==> start .git/HEAD <==
ref: refs/heads/master
==> end .git/HEAD <==

.git/hooks/

...

(The ==> ... <== header/footer is inspired by tail)

Here's the script:

#!/bin/bash

# Globs include hidden files, are null if no matches, recursive with **
shopt -s dotglob nullglob globstar

for file in **; do
    # Print filename with an indicator suffix for filetype
    ls --directory --classify -- "$file"
    filetype="$(file --brief --mime-type -- "$file")"
    # Only print text files
    if [[ $filetype == text/* ]]; then
        printf '==> %s %s <==\n' start "$file"
        cat --show-nonprinting -- "$file"
        printf '==> %s %s <==\n' end "$file"
        echo
    fi
done

It's not pretty, but it works. Color makes it pretty at least:

#!/bin/bash

shopt -s dotglob nullglob globstar

for file in **; do
    ls --directory --classify --color=yes -- "$file"
    filetype="$(file --brief --mime-type -- "$file")"
    # Only print text files
    if [[ $filetype == text/* ]]; then
        printf '\e[32m==> %s %s <==\e[m\n' start "$file"
        cat --show-nonprinting -- "$file"
        printf '\e[31m==> %s %s <==\e[m\n' end "$file"
        echo
    fi
done

Screenshot:

Screenshot showing filename colorized by <code>ls</code>, "start" marker in green, and "end" marker in red

1
  • It's really cool, thank you for your hard work! 💪 Nov 26, 2018 at 6:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.