统计最常用10个命令的脚本
背景
某同学遇到个需求:
- 开发一个脚本
- 可以统计出最长用的10个命令
- 输出有4列, 序号(1~10), 数量(大~小), 占比(大~小), 命令
思路
遇到这么个问题, 自己又不会, 首先去百度了一下, 还真百度到了, 还是2个, 新测可用
统计本机最常用的10个命令(侵权通知删除)
找出最常用的10条history命令的shell脚本(侵权通知删除)
效果如下
![image-20200911191932187](/Users/zhouweixin/Library/Application Support/typora-user-images/image-20200911191932187.png)
详细分析
改写后的脚本
#!/bin/bash
cat ~/.bash_history | awk '{ list[$1]++; }
END {
total=0;
for(k in list){
total=total+list[k];
}
for(k in list){
printf("%d %.4f %s
", list[k], list[k]/total, k)
}
}' | sort -nrk 1 | head -n 10 | awk '{printf("%d %d %.4f %s
", NR, $1, $2, $3)}'
相关知识点
1 如何显示历史命令
history
可以显示所有的历史命令, 直接在终端中输入history
命令即可
查询最新的n条命令, 返回的是不重复的n条件, 重复的不计算在内
history -n
$ history -3
2543 whatis history
2544 history
2545* history 2
2546* history -n 2
2547* history -2
2548* history -10
2549* history -3
2550* history -10
2551* history -20
2552* history -3
2553 hisgory -3
虽然返回的数量超过了3, 但是标*的表示为重复命令, 不重复的有3条
2 历史命令的存储
用户在终端中操作的命令, 在关闭终端时会自动保存到文件中, 一般是.bash_history文件, 最多保存1000条
可以通过环境变量修改存储文件与保存的最大条数
HISTFILE
: 表示命令存储的文件名, 可以通过export HISTFILE=~/.cmd_file
修改
HISTFILESIZE
: 表示最大存储的数量, 可以通过export HISTFILESIZE=2000
修改
$ echo $HISTFILE
/Users/zhouweixin/.bash_history
$ echo $HISTFILESIZE
1000
3 命令cat
查询文件的内容有许多命令, 功能描述如下表所述
命令 | 功能 | 备注 |
---|---|---|
cat | cat(英文全拼:concatenate)命令用于连接文件并打印到标准输出设备上(如terminal) | |
more | 与cat功能相同, 区别在于可以一页一页的输出, 空格翻页 | |
less | less 与 more 类似, 使用 less 可以随意浏览文件, 而且 less 在查看之前不会加载整个文件 | |
head | head命令可用于查看文件的开头部分的内容 | |
tail | tail 命令可用于查看文件尾部的内容 |
4 命令|
脚本中用到了管理命令|
, 其功能是将左边命令的输出作为右边命令的输入
例如: 有一个文件名为go.mod, 内容如下
module zwx/learning/gin-demo-1
go 1.12
require (
code.byted.org/gin/ginex v1.6.11
github.com/cespare/xxhash v1.1.0 // indirect
github.com/gin-gonic/gin v1.6.3
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
)
经过前面的了解我们知道命令cat go.mod
可以把该文件的内容打印到终端, 如下所示
$ cat go.mod
module zwx/learning/gin-demo-1
go 1.12
require (
code.byted.org/gin/ginex v1.6.11
github.com/cespare/xxhash v1.1.0 // indirect
github.com/gin-gonic/gin v1.6.3
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
)
假如我们并不想打印所有的内容, 仅想打印包含indirect行的内容, 则可以利用管道|
, 如下所示
$ cat go.mod | grep indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
管道|
把左侧命令cat
的输出重定向作为右侧命令grep
的输入(grep命令逐行判断是否包含indirect内容)
类似连接多个命令符号有许多, 一定来看几个
命令 | 功能 | 备注 |
---|---|---|
; | 连接多个命令, 顺序执行, 成功失败互不影响 | 示例: mkdir mydir; cd mydir |
> | 输出重定向, 将左侧命令的输出重定向到右侧文件 | 示例: cat a.txt > b.txt |
< | 输入重定向, 将右侧文件的内容作为左侧命令的输入 | |
& | 用于命令后, 表示后台运行命令 | |
&& | 逻辑与, 只有左侧命令为true, 右侧命令才会执行 | |
|| | 逻辑或, 只有左侧命令为false, 右侧才会执行 |
5 命令awk
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
使用详情可参考
6 命令sort
sort命令用于将文本文件内容加以排序, 以行为单位来排序
相关参数
- -b 忽略每行前面开始出的空格字符。
- -c 检查文件是否已经按照顺序排序。
- -d 排序时,处理英文字母、数字及空格字符外,忽略其他的字符。
- -f 排序时,将小写字母视为大写字母。
- -i 排序时,除了040至176之间的ASCII字符外,忽略其他的字符。
- -m 将几个排序好的文件进行合并。
- -M 将前面3个字母依照月份的缩写进行排序。
- -n 依照数值的大小排序。
- -u 意味着是唯一的(unique),输出的结果是去完重了的。
- -o<输出文件> 将排序后的结果存入指定的文件。
- -r 以相反的顺序来排序。
- -t<分隔字符> 指定排序时所用的栏位分隔字符。
- +<起始栏位>-<结束栏位> 以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
- --help 显示帮助。
- --version 显示版本信息。