golang 实现一个简单的命令行进度条

由于有时候跑脚本几个小时看不到进度,所以想着写一个简单的命令行的进度条。类似下面这样的

golang 实现一个简单的命令行进度条

其中的原理主要是\r回车符(将光标移动到行首)。这样的话就可以重新打印一行以覆盖之前的那一行。

func main() {
    for i := 0; i < 10; i++ {
        fmt.Printf("\r####")
    }
}
// &#x7ED3;&#x679C;&#xFF1A;&#x53EA;&#x4F1A;&#x6253;&#x5370;&#x4E00;&#x884C;
// ####

首先来看进度条的结构。主要就是current:当前进度,和一共的任务数量total。

type Bar struct {
    mu      sync.Mutex
    graph   string    // &#x663E;&#x793A;&#x7B26;&#x53F7;
    rate    string    // &#x8FDB;&#x5EA6;&#x6761;
    percent int       // &#x767E;&#x5206;&#x6BD4;
    current int       // &#x5F53;&#x524D;&#x8FDB;&#x5EA6;&#x4F4D;&#x7F6E;
    total   int       // &#x603B;&#x8FDB;&#x5EA6;
    start   time.Time // &#x5F00;&#x59CB;&#x65F6;&#x95F4;
}

初始化

func NewBar(current, total int) *Bar {
    bar := new(Bar)
    bar.current = current
    bar.total = total
    bar.start = time.Now()
    if bar.graph == "" {
        bar.graph = "&#x2588;"
    }
    bar.percent = bar.getPercent()
    for i := 0; i < bar.percent; i += 2 {
        bar.rate += bar.graph //&#x521D;&#x59CB;&#x5316;&#x8FDB;&#x5EA6;&#x6761;&#x4F4D;&#x7F6E;
    }
    return bar
}

func NewBarWithGraph(start, total int, graph string) *Bar {
    bar := NewBar(start, total)
    bar.graph = graph
    return bar
}

计算当前百分比

根据当前的进度和总的进度来计算任务进行的百分比。

func (bar *Bar) getPercent() int {
    return int((float64(bar.current) / float64(bar.total)) * 100)
}

获取当前花费时间

计算当前花费了多少时间 h表示小时,m表示分钟,s表示多少秒。

func (bar *Bar) getTime() (s string) {
    u := time.Now().Sub(bar.start).Seconds()
    h := int(u) / 3600
    m := int(u) % 3600 / 60
    if h > 0 {
        s += strconv.Itoa(h) + "h "
    }
    if h > 0 || m > 0 {
        s += strconv.Itoa(m) + "m "
    }
    s += strconv.Itoa(int(u)%60) + "s"
    return
}

加载进度条

使用fmt.Printf 将光标设置到行首并打印进度条,以覆盖上一个进度条。

func (bar *Bar) load() {
    last := bar.percent
    bar.percent = bar.getPercent()
    if bar.percent != last && bar.percent%2 == 0 {
        bar.rate += bar.graph
    }
    fmt.Printf("\r[%-50s]% 3d%%    %2s   %d/%d", bar.rate, bar.percent, bar.getTime(), bar.current, bar.total)
}

设置进度

设置具体的完成任务数,或者任务数加或者减某个值。

func (bar *Bar) Reset(current int) {
    bar.mu.Lock()
    defer bar.mu.Unlock()
    bar.current = current
    bar.load()

}

func (bar *Bar) Add(i int) {
    bar.mu.Lock()
    defer bar.mu.Unlock()
    bar.current += i
    bar.load()
}

调用示例

func main() {

    b := bar.NewBar(0,1000)
    for i := 0 ;i < 1000; i++ {
        b.Add(1)
        time.Sleep(time.Millisecond*10)
    }

}

至此以上就是全部的代码,非常简单,只是指在跑一些简单任务的时候能有一个提示。

Original: https://www.cnblogs.com/ourongxin/p/15997022.html
Author: EthanWell
Title: golang 实现一个简单的命令行进度条

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/516400/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 基于LSM的Key-Value数据库实现WAL篇

    上篇文章简单的实现了基于LSM数据库的初步版本,在该版本中如数据写入到内存表后但还未持久化到SSTable排序字符串表,此时正好程序崩溃,内存表中暂未持久化的数据将会丢失。 引入W…

    Go语言 2023年5月25日
    064
  • Go语言基础笔记

    Go语言基础语法:https://note.youdao.com/noteshare?id=12098a23b490260282f6b7c347ab182f Go语言内建容器:ht…

    Go语言 2023年5月29日
    085
  • Go微服务框架-2.Go语言RPC编程实践

    Go语言实现RPC编程 上节课我们对RPC知识做了介绍,讲解了RPC的原理,通过图示方式讲解了RPC的内部执行过程。本节课,我们继续来学习RPC相关的内容。 在Go语言官方网站的p…

    Go语言 2023年5月29日
    068
  • 基于知名微服务框架go-micro开发gRPC应用程序

    go-micro是golang的一个微服务框架。 go-micro各个版本之间的兼容性问题一直被诟病,前几年go-micro更是分化出了两个分支: 一个延续了go-micro,只不…

    Go语言 2023年5月25日
    0140
  • websocket:二.Golang实现Websocket消息通知

    我们在设计产品的时候通常都会遇到消息通知的时候,比如用户下单支付成功,比如用户有站内信来可以实时通知。而http是单向的,客户端请求,服务端返回,这次请求就已经结束。而websoc…

    Go语言 2023年5月25日
    068
  • Go easyjson使用技巧

    原文链接:http://www.zhoubotong.site/post/37.html 如果使用go语言自带的json库,使用的是反射,而go语言中反射性能较低。easyjson…

    Go语言 2023年5月25日
    068
  • 在开发中将git运用自如

    写这篇文章的初衷是记录自己在开发中使用git遇到的问题和如何利用git进行高效的开发。个人理解来看,很多人对git运用不自如主要是两方面的原因:1、死记硬背命令,这个其实可以通过h…

    Go语言 2023年5月25日
    054
  • Go xmas2020 学习笔记 01-14 上篇

    课程地址 go-class-slides/xmas-2020 at trunk · matt4biz/go-class-slides (github.com) 主讲老师 Matt …

    Go语言 2023年5月25日
    080
  • Go语言之函数

    函数就是一块执行特定任务的代码,在输入源的基础上通过一些算法生成预期的输出。 Go 语言中的函数声明语法如下: func 函数名(参数名 类型,参数名 类型)(返回值1类型,返回值…

    Go语言 2023年5月25日
    042
  • Go语言学习笔记-结构体(Struct)

    Go语言结构体 1、概念结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员。Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不…

    Go语言 2023年5月25日
    063
  • 【golang】pprof性能调优工具的具体使用(带案例)

    前言 大晚上的,老是刷到有关pprof的文章,忍不住看了几篇文章…写个学习笔记记录下~ 正文: 1.pprof是什么? pprof是go内置的性能调优工具,可以借助一些…

    Go语言 2023年5月25日
    081
  • GO语言 文件操作实例

    package main import ( "bufio" "fmt" "io/ioutil" "os&quo…

    Go语言 2023年5月29日
    056
  • 听说,99% 的 Go 程序员都被 defer 坑过

    先声明:我被坑过。 出问题就对了,这个小东西坏的很,一不留神就出错。 所以,面对这种情况,我们今天就不讲道理了。直接把我珍藏多年的代码一把梭,凭借多年踩坑经历和写 BUG 经验,我…

    Go语言 2023年5月25日
    072
  • go微服务框架Kratos笔记(五)使用nacos作为服务注册和服务发现中心

    引言 上篇介绍了如何使用nacos作为配置管理中心,并使用viper来解析配置官方介绍nacos不仅可以用来做配置中心还支持服务注册、发现以及动态DNS服务功能 nacos的安装 …

    Go语言 2023年5月25日
    055
  • [原创]Golang一行代码给钉钉群推送消息

    [原创]Golang一行代码给钉钉群推送消息 钉钉本来就是工具,只是boss把你变成了工具. — 麦·卡隆 今天朋友扔给我个某签到脚本,让我做推送功能. 我迅速从吃灰收藏夹里掏出S…

    Go语言 2023年5月25日
    051
  • gofs使用教程-基于golang的开源跨平台文件同步工具

    gofs是基于golang开发的一款开箱即用的跨平台文件同步工具,支持在本地磁盘之间同步、从远程服务器同步变更到本地、将本地文件变更推送到远程服务器三种模式。开源地址如下:Gith…

    Go语言 2023年5月25日
    057
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球