最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Go語言實(shí)現(xiàn)類似tree命令的小程序

 更新時(shí)間:2022年10月27日 14:10:32   作者:用戶7841456085940  
tree?命令是一個(gè)小型的跨平臺(tái)命令行程序,用于遞歸地以樹狀格式列出或顯示目錄的內(nèi)容。本文將通過Go語言實(shí)現(xiàn)類似tree命令的小程序,需要的可以參考一下

需求

寫一個(gè)簡版類似于unix tree命令的go語言小程序,如下參數(shù)仿照于tree命令的文檔

該小程序支持的功能如下:

mtree命令默認(rèn)打印以層級(jí)結(jié)構(gòu)打印所有目錄和文件,默認(rèn)以字母排序,支持以下參數(shù)

mtree [-adfLopugshDtr]

列出相關(guān)參數(shù)

-d  僅列出目錄

-L  指定需要打印目錄結(jié)構(gòu)的層數(shù)

-o filename 將結(jié)果輸出到指定文件

文件相關(guān)參數(shù)

-f  打印每個(gè)文件基于當(dāng)前位置的全路徑

-p 打印每個(gè)文件的權(quán)限

-u 打印屬主名稱

-g 打印屬組名稱

-s 打印文件大小

-h 打印文件大小,以更加人性化的方式,會(huì)帶上單位,比如 K、M、G、T

-D 打印文件最后的修改時(shí)間

排序相關(guān)參數(shù)

-t 以最后修改時(shí)間排序輸出

eg:

命令: ./main -u -g -p -D  -s -o tmp.txt

tmp.txt文件內(nèi)容如下

.
├── [-rwxr-xr-x root    root        2138809    Oct 26 2022] main
├── [-rw-r--r-- root    root        2009    Oct 25 2022] tmp.txt
└── [drwxr-xr-x root    root        4096    Mar 14 2022] workspace
    ├── [drwxr-xr-x root    root        4096    Mar 14 2022] cppProj
    │   ├── [drwxr-xr-x root    root        4096    Mar 14 2022] dockerExecDemo
    │   ├── [-rw-r--r-- root    root        398    Mar 14 2022] exec.cpp
    │   └── [-rwxr-xr-x root    root        16872    Mar 14 2022] set_ns
    ├── [drwxr-xr-x root    root        4096    Mar 16 2022] k8s
    │   ├── [drwxr-xr-x root    root        4096    Mar 17 2022] _05
    │   │   ├── [drwxr-xr-x root    root        4096    Mar 16 2022] _15
    │   │   │   ├── [-rw-r--r-- root    root        10    Mar 16 2022] password.txt
    │   │   │   ├── [-rw-r--r-- root    root        405    Mar 16 2022] test_projected_volumn.yml
    │   │   │   └── [-rw-r--r-- root    root        7    Mar 16 2022] username.txt
    │   │   ├── [drwxr-xr-x root    root        4096    Mar 17 2022] _17
    │   │   │   └── [-rw-r--r-- root    root        340    Mar 16 2022] nginx-deployment.yaml
    │   │   └── [drwxr-xr-x root    root        4096    Mar 17 2022] _18
    │   │       ├── [-rw-r--r-- root    root        165    Mar 17 2022] srv.yml
    │   │       └── [-rw-r--r-- root    root        346    Mar 17 2022] statefulset.yaml
    │   ├── [-rwxrwxrwx root    root        313    Jan 26 2022] nginx.yaml
    │   ├── [-rw-r--r-- root    root        197    Mar 16 2022] nginx2.yml
    │   └── [-rw-r--r-- root    root        188    Jan 26 2022] nginx_service.yaml
    └── [drwxr-xr-x root    root        4096    Jan 28 2022] podDemo
        └── [-rw-r--r-- root    root        201    Jan 28 2022] nginx.yaml

目的

在個(gè)人mac電腦上,想在終端里面看看目錄結(jié)構(gòu),奈何網(wǎng)絡(luò)條件不好,tree命令沒有安裝成功,于是動(dòng)手自己寫一個(gè)tree命令的想法油然而生; 同時(shí)又可以熟悉go語言標(biāo)準(zhǔn)庫,提高編碼能力,本程序主要涉及go pkg有:flag、os、fs、path、filepath等

需求分析

針對(duì)上面的輸出顯示,可以把每一行的信息分為

  • 文件路徑,文件名稱,文件的相對(duì)路徑, eg: ./workspace/k8s/_05/_15/password.txt
  • 文件屬性,權(quán)限,屬主,屬組,大小,時(shí)間 eg: [root root 10]
  • 前綴 eg: │ │ │ └──

代碼思路:針對(duì)程序當(dāng)前執(zhí)行路徑,遍歷子目錄節(jié)點(diǎn),如果子節(jié)點(diǎn)同樣是目錄的話,則遞歸遍歷;在遞歸遍歷的過程中,獲取每一個(gè)文件的相關(guān)屬性信息; 同時(shí),對(duì)于程序指定的參數(shù),可以分為屬性類參數(shù)和控制類參數(shù)

  • 屬性類參數(shù)有: -u -g -f -p -s -h
  • 控制類參數(shù)有: -L -o -d -D -t

對(duì)于屬性類的參數(shù),定義不同的filter,在遍歷的過程中,每一個(gè)文件節(jié)點(diǎn),都經(jīng)過過濾器過濾,用于填充對(duì)應(yīng)的屬性信息; 對(duì)于控制類的參數(shù),則貫穿于程序過程中,用于控制不同的行為

這里重點(diǎn)分析下如何輸出前綴的這種層級(jí)關(guān)系的前綴,以下述目錄結(jié)構(gòu)進(jìn)行舉例說明:

目錄結(jié)構(gòu)

.
└── workspace
    ├── cppProj
    │   └── dockerExecDemo
    ├── k8s
    │   └── _05
    │       ├── _15
    │       ├── _17
    │       └── _18
    └── podDemo

眾所周知,unix文件系統(tǒng)是樹狀結(jié)構(gòu);因此,這里首先就目錄結(jié)構(gòu)抽象成樹結(jié)構(gòu),如下圖,左上角是對(duì)應(yīng)的目錄結(jié)構(gòu),右邊是抽象的樹狀結(jié)構(gòu):

圖豎著看可能還不夠清晰,把該樹結(jié)構(gòu)橫過來,這樣就可以很好的用該樹結(jié)構(gòu)和目錄的層級(jí)關(guān)系進(jìn)行一一類比了

下面重點(diǎn)分析下如何輸出每一層目錄的前綴,先看└── ├── 是如何確定的,如上目錄結(jié)構(gòu)所示, _18節(jié)點(diǎn)屬于目錄_05的最后一個(gè)節(jié)點(diǎn),因此_18節(jié)點(diǎn)前面為字符串└── ; 一個(gè)目錄中,除了最后一個(gè)節(jié)點(diǎn)前面的字符串為└──,其他節(jié)點(diǎn)前面的字符串都是├── ,這里的前綴字符串很容易就可以總結(jié)得出; 但是對(duì)于節(jié)點(diǎn)dockerExecDemo前面的字符串, 和_18節(jié)點(diǎn)前面的字符串,該如何打印呢? 通過分析我們的樹狀結(jié)構(gòu)可以總結(jié)得出,如果一個(gè)節(jié)點(diǎn)的父親沒有右兄弟,則添加前綴 , 否則添加前綴, 每一個(gè)節(jié)點(diǎn)都以這樣的方式追隨到根結(jié)點(diǎn),就可以得出該節(jié)點(diǎn)的前綴關(guān)系;這里已_15節(jié)點(diǎn)來完整的舉例說明:

  • _15 節(jié)點(diǎn)屬于第一個(gè)節(jié)點(diǎn),因此首先添加前綴 "├──"; 前綴結(jié)果為: "├──"
  • _15 節(jié)點(diǎn)的父親_05沒有右兄弟,因此繼續(xù)添加前綴 " "; 前綴結(jié)果為:" ├──"
  • _05 節(jié)點(diǎn)的父親k8s有右兄弟,因此繼續(xù)添加前綴 "│ "; 前綴結(jié)果為:"│ ├──"
  • k8s 節(jié)點(diǎn)的父親workspace沒有右兄弟,因此繼續(xù)添加前綴 " "; 前綴結(jié)果為:" │ ├──"
  • 最終_15 節(jié)點(diǎn)的整體前綴為 " │ ├── "

上面所述的樹結(jié)構(gòu),go語言的定義如下:

type MFileNode struct {
	Level     int
	ModTime   time.Time
	UserName  string
	Size      int64
	GroupName string
	FileName  string
	IsDir     bool

	Children  []*MFileNode
	Parent    *MFileNode
	Left      *MFileNode
	Right     *MFileNode

	Prefix strings.Builder
	Attr   strings.Builder
	Path   strings.Builder
}

核心遍歷目錄樹的代碼如下,

// Walk 文件結(jié)構(gòu)遍歷目錄樹,構(gòu)造MTree,同時(shí)每一文件節(jié)點(diǎn),都經(jīng)過參數(shù)過濾器進(jìn)行格式化輸出
func Walk(parentMFile *MFileNode, parent, base string, filters *MFilter) error {
	if parentMFile.Level >= level {
		return nil
	}
	dirEntries, err := os.ReadDir(filepath.Join(parent, base))
	if err != nil {
		return err
	}

	if len(dirEntries) == 0 {
		return nil
	}
	parentMFile.Children = make([]*MFileNode, 0, len(dirEntries))
	var pre *MFileNode = nil
	for _, dir := range dirEntries {
		if onlyDir && !dir.IsDir() {
			continue
		}
		childMFile := &MFileNode{
			Level:    parentMFile.Level + 1,
			Children: nil,
			FileName: dir.Name(),
			Parent:   parentMFile,
			Left:     pre,
			IsDir:    dir.IsDir(),
		}
        // 維護(hù)左右兄弟節(jié)點(diǎn)關(guān)系
		if pre != nil {
			pre.Right = childMFile
		}
		pre = childMFile
		info, err := dir.Info()
		if err != nil {
			return err
		}
		// 參數(shù)過濾器
		filters.Exec(childMFile, info)
		parentMFile.Children = append(parentMFile.Children, childMFile)
		if dir.IsDir() {
			err1 := Walk(childMFile, filepath.Join(parent, base), dir.Name(), filters)
			if err1 != nil {
				return err1
			}
		}
	}
	return nil
}

最終程序?qū)崿F(xiàn)的輸出和 unix tree命令輸出對(duì)比如下圖所示,幾乎完整的實(shí)現(xiàn)了自己的目的:

到此這篇關(guān)于基于Go語言實(shí)現(xiàn)類似tree命令的小程序的文章就介紹到這了,更多相關(guān)Go語言 tree命令內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go應(yīng)該如何實(shí)現(xiàn)二級(jí)緩存

    Go應(yīng)該如何實(shí)現(xiàn)二級(jí)緩存

    本文主要介紹了Go二級(jí)緩存,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 一文帶你掌握Golang的反射基礎(chǔ)

    一文帶你掌握Golang的反射基礎(chǔ)

    go的反射是由其標(biāo)準(zhǔn)庫中的reflect包實(shí)現(xiàn),該reflect包實(shí)現(xiàn)了在運(yùn)行時(shí)進(jìn)行反射的能力,本篇主要介紹了reflect的常用的幾個(gè)方法,希望對(duì)大家有所幫助
    2023-02-02
  • Golang內(nèi)存管理之垃圾收集器詳解

    Golang內(nèi)存管理之垃圾收集器詳解

    這篇文章我們主要介紹垃圾收集器的設(shè)計(jì)原理以及Golang垃圾收集器的實(shí)現(xiàn)原理,文中有詳細(xì)的代碼示例及圖文介紹,感興趣的小伙伴跟著小編一起來學(xué)習(xí)吧
    2023-06-06
  • 一文帶你了解Golang中的并發(fā)性

    一文帶你了解Golang中的并發(fā)性

    并發(fā)是一個(gè)很酷的話題,一旦你掌握了它,就會(huì)成為一筆巨大的財(cái)富。所以本文就來和大家一起來聊聊Golang中的并發(fā)性,感興趣的可以了解一下
    2023-03-03
  • ???????Golang實(shí)現(xiàn)RabbitMQ中死信隊(duì)列幾種情況

    ???????Golang實(shí)現(xiàn)RabbitMQ中死信隊(duì)列幾種情況

    本文主要介紹了???????Golang實(shí)現(xiàn)RabbitMQ中死信隊(duì)列幾種情況,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Go中調(diào)用JS代碼(otto)的實(shí)現(xiàn)示例

    Go中調(diào)用JS代碼(otto)的實(shí)現(xiàn)示例

    Otto是一個(gè)用Go語言實(shí)現(xiàn)的JavaScript解釋器,可用于執(zhí)行和操作JavaScript代碼,適合在Go項(xiàng)目中執(zhí)行簡單的JS腳本,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • 最新評(píng)論

    离岛区| 新丰县| 巫溪县| 惠来县| 宁海县| 福泉市| 崇明县| 自治县| 英德市| 迁安市| 威海市| 江孜县| 麻阳| 贺兰县| 岐山县| 宝坻区| 泗洪县| 积石山| 深泽县| 河源市| 壶关县| 临安市| 东至县| 东方市| 田林县| 左权县| 兰西县| 克什克腾旗| 股票| 馆陶县| 关岭| 新蔡县| 晋宁县| 紫金县| 内黄县| 西昌市| 贵港市| 内乡县| 永嘉县| 克拉玛依市| 彰化市|