MENU

无颜色目录树

2021 年 01 月 28 日 • 阅读: 7120 • 后端

Linux Version

➜  LOGI tree /etc/apt
/etc/apt
├── apt.conf.d
│   ├── 01-vendor-ubuntu
│   ├── 01autoremove
│   ├── 01autoremove-kernels
│   ├── 10periodic
│   ├── 15update-stamp
│   ├── 20archive
│   ├── 20auto-upgrades
│   ├── 20packagekit
│   ├── 20snapd.conf
│   ├── 50command-not-found
│   ├── 50unattended-upgrades
│   ├── 70debconf
│   └── 99update-notifier
├── auth.conf.d
├── preferences.d
├── sources.list.bak
├── sources.list.d
│   ├── 163.list
│   ├── 163.list.save
│   └── deadsnakes-ubuntu-ppa-focal.list
└── trusted.gpg.d
    ├── deadsnakes_ubuntu_ppa.gpg
    ├── ubuntu-keyring-2012-archive.gpg
    ├── ubuntu-keyring-2012-cdimage.gpg
    └── ubuntu-keyring-2018-archive.gpg

5 directories, 21 files

Self Implementation

➜  LOGI java DirectoryTree //wsl$/Ubuntu/etc/apt
\\WSL$\UBUNTU\ETC\APT
├── apt.conf.d
│   ├── 01-vendor-ubuntu
│   ├── 01autoremove
│   ├── 01autoremove-kernels
│   ├── 10periodic
│   ├── 15update-stamp
│   ├── 20archive
│   ├── 20auto-upgrades
│   ├── 20packagekit
│   ├── 20snapd.conf
│   ├── 50command-not-found
│   ├── 50unattended-upgrades
│   ├── 70debconf
│   └── 99update-notifier
├── auth.conf.d
├── preferences.d
├── sources.list.bak
├── sources.list.d
│   ├── 163.list
│   ├── 163.list.save
│   └── deadsnakes-ubuntu-ppa-focal.list
└── trusted.gpg.d
    ├── deadsnakes_ubuntu_ppa.gpg
    ├── ubuntu-keyring-2012-archive.gpg
    ├── ubuntu-keyring-2012-cdimage.gpg
    └── ubuntu-keyring-2018-archive.gpg

5 directories, 21 files

Source Code

Rust

use std::{path, fs, io, env};

struct DirectoryTree<'a> {
    file_count: u32,
    directory_count: u32,
    root: &'a str,
}

impl<'a> DirectoryTree<'a> {
    fn print(&mut self) {
        if path::Path::new(self.root).exists() {
            println!("{}", self.root.to_uppercase());
            self.print_sub_tree(self.root, "").err();
            print!("\n{} director{}, {} file{}",
                   self.directory_count,
                   if self.directory_count > 1 { "ies" } else { "y" },
                   self.file_count,
                   if self.file_count > 1 { "s" } else { " " },
            )
        }
    }

    fn print_sub_tree(&mut self, folder: &str, prefix: &str) -> io::Result<()> {
        let children: Vec<_> = fs::read_dir(folder)?
            .map(|res| res.unwrap().path())
            .collect();

        for i in 0..children.len() {
            let child = &children[i];
            let is_last_one = if i == children.len() - 1 { true } else { false };

            println!("{}{}── {}",
                     prefix,
                     if is_last_one { "└" } else { "├" },
                     child.file_name().unwrap().to_str().unwrap());

            if child.is_dir() {
                self.directory_count += 1;
                self.print_sub_tree(child.to_str().unwrap(),
                                    &format!("{}{}\t",
                                             prefix,
                                             if is_last_one { " " } else { "│" }))?;
            } else {
                self.file_count += 1;
            }
        }

        Ok(())
    }
}

fn main() {
    let mut path = ".";
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 {
        path = &args[1];
    }

    DirectoryTree {
        file_count: 0,
        directory_count: 0,
        root: path,
    }.print();
}

C++

#include <iostream>
#include <sstream>
#include <string>
#include <filesystem>

using namespace std;
namespace fs = filesystem;

class DirectoryTree {
private:
    int fileCount;
    int directoryCount;
    const string &root;

    static vector<fs::directory_entry> listFiles(const string &path);

    void printSubtree(const string &folder, const string &prefix);

public:
    explicit DirectoryTree(const string &root);

    void print();
};

vector<fs::directory_entry>
DirectoryTree::listFiles(const string &path) {
    vector<fs::directory_entry> files;
    for (auto &p:fs::directory_iterator(path)) {
        files.push_back(p);
    }
    return files;
}

void
DirectoryTree::printSubtree(const string &folder, const string &prefix) {
    auto children = listFiles(folder);

    for (int i = 0; i < children.size(); ++i) {
        auto child = children.at(i);
        bool isLastOne = i == children.size() - 1;

        cout << prefix << (isLastOne ? "└" : "├")
             << "── " << fs::path(child.path()).filename().string() << endl;

        if (child.is_directory()) {
            directoryCount++;
            printSubtree(child.path().string(),
                         prefix + (isLastOne ? " " : "│") + "    ");
        } else {
            fileCount++;
        }
    }

}

void
DirectoryTree::print() {
    if (fs::exists(root)) {
        cout << root << endl;
        printSubtree(root, "");
        cout << endl
             << directoryCount << " director" << (directoryCount > 1 ? "ies" : "y")
             << ", " << fileCount << " file" << (fileCount > 1 ? "s" : "");
    }
}

DirectoryTree::DirectoryTree(const string &root) : root(root) {
    fileCount = directoryCount = 0;
}


int main(int argc, char *argv[]) {
    system("chcp 65001");

    auto path = ".";
    if (argc > 1) {
        path = argv[1];
    }
    (new DirectoryTree(path))->print();
}

Java

import java.io.File;
import java.util.Locale;

/**
 * @author LOGI
 * @version 1.0
 * @date 2021/1/28 11:03
 */
public class DirectoryTree {
    private final File root;
    private int fileCount;
    private int directoryCount;

    public DirectoryTree(String path) {
        this.root = new File(path);
    }

    public static void main(String[] args) {
        String path = ".";
        if (args.length != 0) {
            path = args[0];
        }
        new DirectoryTree(path).print();
    }

    public void print() {
        if (root.exists()) {
            System.out.println(root.getAbsolutePath().toUpperCase(Locale.ROOT));
            printSubtree(root, "");
            System.out.printf("\n%d director%s, %d file%s",
                    directoryCount,
                    directoryCount > 1 ? "ies" : "y",
                    fileCount,
                    fileCount > 1 ? "s" : "");
        }
    }

    private void printSubtree(File file, String prefix) {
        File[] children = file.listFiles();
        if (children == null) return;

        for (int i = 0; i < children.length; i++) {
            File child = children[i];
            boolean isLastOne = i == children.length - 1;

            System.out.printf("%s%s── %s\n",
                    prefix,
                    isLastOne ? "└" : "├",
                    child.getName());

            if (child.isDirectory()) {
                directoryCount++;
                printSubtree(child,
                        String.format("%s%s\t",
                                prefix,
                                isLastOne ? " " : "│"));
            } else {
                fileCount++;
            }
        }
    }
}

NodeJS

const fs = require('fs');
const path = require('path');

module.exports = class DirectoryTree {
  constructor(path) {
    this.root = path;
    this.fileCount = 0;
    this.directoryCount = 0;
  }
  
  print() {
    if (fs.existsSync(this.root)) {
      console.log(path.resolve(this.root).toUpperCase());
      this.printSubtree(this.root, '');
      console.log(`\n${this.directoryCount} director${this.directoryCount > 1 ? 'ies' : 'y'},`,
        `${this.fileCount} file${this.fileCount > 1 ? 's' : ''}`);
    }
  }

  printSubtree(folder, prefix) {
    const children = fs.readdirSync(folder);
    children.forEach((child, i) => {
      const realpath = path.join(folder, child);
      const isLastOne = i === children.length - 1;

      console.log(`${prefix}${isLastOne ? '└' : '├'}── ${child}`);
      if (fs.statSync(realpath).isDirectory()) {
        this.directoryCount++;
        this.printSubtree(realpath, `${prefix}${isLastOne ? ' ' : '│'}    `);
      } else {
        this.fileCount++;
      }
    });
  }
};

/*
const DirectoryTree = require('./DirectoryTree');
new DirectoryTree(process.argv[2] || '.').print();
*/

Python

import os
import sys


class DirectoryTree:
    def __init__(self, root):
        self.root = root
        self.file_count = 0
        self.directory_count = 0

    def print(self):
        if os.path.exists(self.root):
            print(os.path.abspath(self.root).upper())
            self.print_subtree(self.root, '')
            print(str.format('\n{} director{}, {} file{}',
                             self.directory_count,
                             'ies' if self.directory_count > 1 else 'y',
                             self.file_count,
                             's' if self.file_count > 1 else ''))

    def print_subtree(self, folder, prefix):
        children = os.listdir(folder)
        for i, child_name in enumerate(children):
            child_path = os.path.join(folder, child_name)
            is_last_one = i == len(children) - 1
            print(str.format('{}{}── {}',
                             prefix,
                             '└' if is_last_one else '├',
                             child_name))

            if os.path.isdir(child_path):
                self.directory_count += 1
                self.print_subtree(child_path,
                                   str.format('{}{}\t',
                                              prefix,
                                              '' if is_last_one else '│'))
            else:
                self.file_count += 1


if __name__ == '__main__':
    path = '.'
    if len(sys.argv) != 1:
        path = sys.argv[1]

    DirectoryTree(path).print()

Golang

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "path/filepath"
    "strings"
)

type DirectoryTree struct {
    root           string
    fileCount      int
    directoryCount int
}

func trueToFirst(c bool, s1, s2 string) string {
    return map[bool]string{true: s1, false: s2}[c]
}

func (tree *DirectoryTree) Print() {
    if _, err := os.Stat(tree.root); err == nil {
        abs, err := filepath.Abs(tree.root)
        if err != nil {
            panic("can not get abs path")
        }

        fmt.Println(strings.ToUpper(abs))
        tree.printSubtree(tree.root, "")
        fmt.Printf("\n%d director%s, %d file%s",
            tree.directoryCount,
            trueToFirst(tree.directoryCount > 1, "ies", "y"),
            tree.fileCount,
            trueToFirst(tree.fileCount > 1, "s", ""))
    }
}

func (tree *DirectoryTree) printSubtree(folder string, prefix string) {
    children, err := ioutil.ReadDir(folder)
    if err != nil {
        panic("can not read dir")
    }

    for i, child := range children {
        realpath := filepath.Join(folder, child.Name())
        isLastOne := i == len(children)-1

        fmt.Printf("%s%s── %s\n",
            prefix,
            trueToFirst(isLastOne, "└", "├"),
            child.Name())

        if child.IsDir() {
            tree.directoryCount++
            tree.printSubtree(realpath, fmt.Sprintf("%s%s\t",
                prefix,
                trueToFirst(isLastOne, " ", "│")))
        } else {
            tree.fileCount++
        }
    }
}

func main() {
    path := "."
    if len(os.Args) > 1 {
        path = os.Args[1]
    }

    (&DirectoryTree{root: path}).Print()
}

Shell

#!/usr/bin/env bash

file_count=0
directory_count=0

function print()
{
  local root="$1"
  [ "$(ls "$root" 1>/dev/null)" ] && return

  echo "${root^^}"
  print_subtree "$root" ""
  printf "\n%d director%s %d file%s" \
    "$directory_count" \
    "$([ "$directory_count" -gt 1 ] && echo "ies" || echo "y")" \
    "$file_count" \
    "$([ "$file_count" -gt 1 ] && echo "s" || echo "")"
}

function print_subtree()
{
  local folder="$1"
  local prefix="$2"
  local children
  mapfile -t children < <(ls "$folder")

  local i
  local realpath
  for (( i = 0; i < ${#children[@]}; i++ )); do
      realpath="$folder"/${children[$i]}

      printf "%s%s── %s\n" \
        "$prefix" \
        "$([ "${#children[@]}" -eq "$((i + 1))" ] && echo "└" || echo "├")" \
        "${children[$i]}"

      if [ -d "$realpath" ]; then
        ((directory_count++))
        print_subtree "$realpath" \
          "$prefix$([ "${#children[@]}" -eq "$((i + 1))" ] && echo " " || echo "│")   "
      else
        ((file_count++))
      fi
  done
}

path="."
if [ "$1" ]; then
    path="$1"
fi
print "$path"

PowerShell

$script:fileCount = 0
$script:directoryCount = 0

function Convert-TrueToFirst($condition, $firstString, $secondString)
{
    if ($condition)
    {
        return $firstString
    }
    return $secondString
}

function Out-DirectoryTree($root)
{
    if (Test-Path $root)
    {
        $root.ToUpper()
        Out-Subtree $root ""
        "{0} director{1}, {2} file{3}" -f `
            $script:directoryCount, `
            (Convert-TrueToFirst ($script:directoryCount -gt 1)  'ies' 'y'), `
            $script:fileCount, `
            (Convert-TrueToFirst ($script:fileCount -gt 1) 's' '')
    }
}

function Out-Subtree($folder, $prefix)
{
    $children = Get-ChildItem $folder
    for ($i = 0; $i -lt $children.Count; $i++) {
        $child = $children[$i]
        $isLastOne = ($i -eq ($children.Count - 1))

        "{0}{1}── {2}" -f `
            $prefix,  `
            (Convert-TrueToFirst $isLastOne '└' '├'),  `
            $child.Name

        if ( $child.Mode.Contains('d'))
        {
            $script:directoryCount++
            Out-Subtree $child.FullName `
                    ("{0}{1}    " -f $prefix, (Convert-TrueToFirst $isLastOne ' ' '│'))
        }
        else
        {
            $script:fileCount++
        }
    }
}

$path = '.'
if ($args.Count -gt 0)
{
    $path = $args[0]
}
Out-DirectoryTree $path
TG 大佬群 QQ 大佬群

最后编辑于: 2021 年 02 月 02 日
返回文章列表 文章二维码
本页链接的二维码
打赏二维码
添加新评论

Loading captcha...

已有 3 条评论
  1. 不吃猫的鱼 不吃猫的鱼   Windows 10 x64 Edition  Google Chrome 88.0.4324.190

    博主你这个高亮代码是用什么插件实现的啊,我和你同主题显示怎么不一样呢#(喜极而泣)

    1. LOGI LOGI   Windows 10 x64 Edition  Google Chrome 88.0.4324.190

      @不吃猫的鱼https://mirages.docs.get233.com/#/docs/advance/highlight-extend

  2. 站元素主机 站元素主机   Windows 10 x64 Edition  Firefox 85.0

    学习了 赞一个