作业4

1. 实验要求
​ 使用 golang 开发 开发 Linux 命令行实用程序 中的 selpg

2. 实验步骤
开发Linux命令行实用程序

安装pflag
在终端输入以下命令

   go get github.com/spf13/pflag #install到本地
   go test github.com/spf13/pflag #test
   import flag "github.com/spf13/pflag" #导入,可以继续使用flag



参数处理
输入以下代码,并保存为test.go

package main

import (
    "fmt"

    flag "github.com/spf13/pflag"
)

func main() {
    var s int
    flag.IntVarP(&s, "start", "s", 0, "startPage")
    flag.Parse()
    fmt.Printf("%d\n", s)
}


将终端工作路径切换到当前工作目录下
$ go build test.go
$ ./test
0
$ ./test -s10
10
$ ./test -s20
20
$ ./test --start=30
30

结合终端输出的结果,分析以下test.go代码。
flag.IntVarP定义命令行参数
&s——将命令行参数的值绑定到s变量上
“start”——可以通过- -start=30为参数赋值
“s“——可以通过-s10为参数赋值
最后要通过flag.Parse解析
 

2.1 项目所涉及的Go语言知识点
​ 做这次作业需要使用的Go语言的知识点大概有以下几个方面

​ ① 函数

​ ② 结构体

​ ③ 参数的绑定

​ ④ 异常处理

​ ⑤ 文件读写

​ ⑥ 命令行参数的解析

函数介绍

func getArgs(args *Args) :定义命令行参数
func checkArgs(args *Args): 检查参数的合法性
func getReader(args *Args) *bufio.Reader:获取bufio.Reader对象
func execution(args *Args):执行文件读入写出
func readByL(args *Args, reader *bufio.Reader, writer *bufio.Writer):按行读入,并输出到标准输出
func readByF(args *Args, reader *bufio.Reader, writer *bufio.Writer) :按页读入,并输出到标准输出
func readByLWithD(args *Args, reader *bufio.Reader, writer io.WriteCloser) :按行读入,并由管道输出到"-dXXX"
func readByFWithD(args *Args, reader *bufio.Reader, writer io.WriteCloser) :按页读入,并由管道输出到"-dXXX"

 

2.2 理解selpg
​ selpg 是一个自定义命令行程序,全称select page,即从源(标准输入流或文件)读取指定页数的内容到目的地(标准输出流或给给打印机打印)

2.3 Go使用flag包解释命令行参数
flag包能解析的参数有如下四种形式,使用的时候分三种类型:

类型一
cmd -flag=x // 支持所有类型
cmd -flag x // 只支持非bool类型

类型二
cmd -flag // 只支持bool类型

类型三
cmd abc // 没有flag的参数

2.3.1 类型一
类型一定义参数有两种形式,下方Xxx代表类型

2.3.1.1 类型一定义参数
flag.Xxx()

flag.String(), Bool(), Int() 这种形式返回一个指向该参数的指针

例子

var date = flag.Int("d", 20171107, "help message for date") 

flag.Parse()

(注意: date 是指向 -d 参数值的指针)

​ 若在命令行输入 -d=20121212 -a=20 或者 -d 20121212 -a 20,则我们在程序中即可用 *date 取得 -d 的值20121212

​ 若只输入 -a=20 或者 -a 20,因为缺省标志 -d ,则 *date 取到的是 -d 定义中的默认值 20171107

flag.XxxVar()

flag.StringVar(), BoolVar(), IntVar() 这种形式把参数绑定到一个变量

例子

var age int

flag.IntVar(&age, "a", 18, "help message for age")

flag.Parse()


​ 命令行输入-d=20121212 -a=20 或者-d=20121212 -a 20 ,在程序里 变量age 则获取到 -a 的值 20

​ 若只输入-d=20121212 或者-d=20121212,缺省标志-a, 则 变量age 获取定义中的默认值 18

2.3.1.2 类型一解析参数
​ 注意到上面例子最后都带有一行 flag.Parse()

​ 因为定义好参数后,只有调用方法 flag.Parse() 解析命令行参数到定义的flag,这样我们才能使用上面两个例子的 *date 和 age 取得对应flag的参数值

2.3.2 类型二
cmd -flag //该形式只支持bool类型,对应的值是1, 0, t, f, true, false, TRUE, FALSE, True, False

​ 默认的,如果我们在命令行里提供了-flag,则其对应的值为true,否则为flag.Bool/BoolVar中指定的默认值;如果希望显示设置为false则使用-flag=false。

例子

var exist_f = flag.Bool("f", false, "help message for format")

flag.Parse()


​ 当在命令行输入 -d=123 -f 时,程序里 *exist_f 的值就为 true 了

​ 若命令行只输入 -d=123 时,因为缺省-f,*exist_f 的值为事先定义中默认的 false

2.3.3 类型三
cmd abc //没有flag的参数

​ 1.通过 flag.Args() 获取非flag参数列表

​ 2.通过 flag.Arg(i) 来获取非flag命令行第i个参数,i 从 0 开始

​ 3.通过flag.NArg() 获得非flag参数个数

例子

​ 当命令行敲入 -d 20121212 -a 20 Wang yx ,最后两个值即为不带标志的参数

flag.Parse()

var fullName = flag.Args() // fullName = ['Wang', 'yx']

var firstName = flag.Arg(0) // firstName = Wang

var lastName = flag.Arg(1) // lastName = yx

var num = flag.NArg() // num = 2


2.4 命令行参数设计
selpg -s startPage -e endPage [-l linePerPage | -f ][-d dest] filename

必需标志以及参数:

-s,后面接开始读取的页号 int
-e,后面接结束读取的页号 int
s和e都要大于1,并且s <= e,否则提示错误
可选参数:

-l,后面跟行数 int,代表多少行分为一页,不指定 -l 又缺少 -f 则默认按照72行分一页
-f,该标志无参数,代表按照分页符’\f’ 分页
-d,后面接打印机标号,用于将内容传送给打印机打印 我没有打印机用于测试,所以当使用 -d destination(随便一个字符串作参数)时,就会通过管道把内容发送给 grep命令,并把grep处理结果显示到屏幕

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值