golang实时更新的UNIX wc命令替代插件lwc的使用
Golang实时更新的UNIX wc命令替代插件lwc的使用
简介
lwc是一个实时更新的UNIX wc
命令替代工具。与标准wc
命令不同,lwc在计数过程中会实时更新输出结果。
安装方法
二进制安装
可以从发布页面下载预编译的二进制文件,解压到PATH路径下即可使用。
源码安装
使用go get命令从源码安装:
go get -u github.com/timdp/lwc/cmd/lwc
Debian/Ubuntu安装
对于Debian兼容的Linux发行版(如Ubuntu),可以使用实验性的APT仓库:
echo 'deb [allow-insecure=yes] https://tmdpw.eu/lwc-releases/debian/ any main' |
sudo tee /etc/apt/sources.list.d/lwc.list
sudo apt update
sudo apt install lwc
使用方法
基本命令格式:
lwc [OPTION]... [FILE]...
lwc [OPTION]... --files0-from=F
如果不指定任何选项,lwc将统计标准输入中的行数、单词数和字节数,并输出到标准输出。与wc
不同,lwc会在计数过程中实时更新输出。
支持的标准wc
选项:
--lines
或-l
:统计行数--words
或-w
:统计单词数--chars
或-m
:统计字符数--bytes
或-c
:统计字节数--max-line-length
或-L
:显示最长行的长度--files0-from=F
:从文件读取输入--help
:显示帮助信息--version
:显示版本信息
额外选项:
--interval=TIME
或-i TIME
:设置更新间隔时间(毫秒),默认100ms
使用示例
统计大文件行数
lwc --lines big-file
统计慢命令输出的行数和单词数
slow-command | lwc --lines --words
测试lwc的吞吐量(按Ctrl+C退出)
lwc --bytes < /dev/urandom
注意事项
-
--words
和--chars
选项的行为与标准wc
略有不同,某些二进制数据可能会得到不同的值 -
lwc虽然速度很快,但性能无法与C实现的
wc
相比,原因可能是:- 代码没有针对性能优化
- Go实现无法与C实现匹敌
作者
Tim De Pauw
许可证
MIT
更多关于golang实时更新的UNIX wc命令替代插件lwc的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实时更新的UNIX wc命令替代插件lwc的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang实现的实时更新版wc命令替代工具lwc
lwc是一个用Golang实现的实时更新的wc命令替代工具,它不仅提供传统wc的计数功能,还能实时监控文件变化并更新统计结果。
功能特点
- 实时监控文件变化并更新统计
- 支持传统wc的所有计数功能(行数、单词数、字符数、字节数)
- 支持彩色输出
- 支持多文件处理
安装方法
go install github.com/tj/go-lwc@latest
基本使用示例
package main
import (
"fmt"
"os"
"github.com/tj/go-lwc"
)
func main() {
// 创建lwc实例
counter := lwc.New()
// 监控单个文件
if err := counter.Watch("example.txt"); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
// 开始实时监控
counter.Start()
}
完整功能示例
package main
import (
"flag"
"fmt"
"os"
"time"
"github.com/fatih/color"
"github.com/tj/go-lwc"
)
func main() {
// 解析命令行参数
var (
lines = flag.Bool("l", false, "count lines")
words = flag.Bool("w", false, "count words")
chars = flag.Bool("m", false, "count characters")
bytes = flag.Bool("c", false, "count bytes")
interval = flag.Duration("i", 500*time.Millisecond, "poll interval")
noColor = flag.Bool("no-color", false, "disable color")
all = flag.Bool("a", false, "count all (lines, words, bytes)")
)
flag.Parse()
// 如果没有指定任何计数选项,默认显示全部
if !*lines && !*words && !*chars && !*bytes && !*all {
*all = true
}
// 初始化颜色
if *noColor {
color.NoColor = true
}
// 创建计数器
counter := lwc.New()
counter.Interval = *interval
// 添加要监控的文件
for _, path := range flag.Args() {
if err := counter.Watch(path); err != nil {
fmt.Fprintf(os.Stderr, "error watching %q: %s\n", path, err)
os.Exit(1)
}
}
// 如果没有指定文件,从stdin读取
if len(flag.Args()) == 0 {
if err := counter.WatchFile(os.Stdin); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
}
// 设置输出处理函数
counter.Handler = func(path string, counts lwc.Counts) {
output := []interface{}{}
// 添加文件名(如果有)
if path != "" {
output = append(output, color.BlueString("%s", path))
}
// 添加计数结果
if *all || *lines {
output = append(output, color.GreenString("%d", counts.Lines))
}
if *all || *words {
output = append(output, color.YellowString("%d", counts.Words))
}
if *all || *chars {
output = append(output, color.MagentaString("%d", counts.Chars))
}
if *all || *bytes {
output = append(output, color.CyanString("%d", counts.Bytes))
}
// 打印结果
fmt.Println(output...)
}
// 开始监控
if err := counter.Start(); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
}
自定义实现简化版lwc
如果你想了解原理,这里是一个简化版的实现:
package main
import (
"bufio"
"fmt"
"io"
"os"
"time"
)
type Counts struct {
Lines int
Words int
Chars int
Bytes int
}
func count(r io.Reader) (Counts, error) {
var c Counts
scanner := bufio.NewScanner(r)
for scanner.Scan() {
c.Lines++
line := scanner.Text()
c.Words += len(bufio.ScanWords([]byte(line), true)
c.Chars += len([]rune(line)) + 1 // +1 for newline
c.Bytes += len(scanner.Bytes()) + 1
}
return c, scanner.Err()
}
func watchFile(path string, interval time.Duration, handler func(Counts)) error {
lastMod := time.Time{}
for {
stat, err := os.Stat(path)
if err != nil {
return err
}
if stat.ModTime().After(lastMod) {
file, err := os.Open(path)
if err != nil {
return err
}
counts, err := count(file)
file.Close()
if err != nil {
return err
}
handler(counts)
lastMod = stat.ModTime()
}
time.Sleep(interval)
}
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: lwc <file>")
os.Exit(1)
}
handler := func(c Counts) {
fmt.Printf("\rLines: %d, Words: %d, Chars: %d, Bytes: %d",
c.Lines, c.Words, c.Chars, c.Bytes)
}
if err := watchFile(os.Args[1], 500*time.Millisecond, handler); err != nil {
fmt.Printf("\nError: %v\n", err)
os.Exit(1)
}
}
使用建议
- 对于大文件,适当增加轮询间隔以减少系统负载
- 可以使用管道将其他命令的输出传递给lwc:
tail -f logfile | lwc
- 结合
-a
参数可以查看所有统计信息 - 在脚本中使用时,可以添加
--no-color
参数禁用彩色输出
lwc是一个简单但强大的工具,特别适合在开发过程中实时监控日志文件或输出变化的统计信息。